Static composite approach generates fatal error
Closed this issue · 3 comments
Hi.
I was looking to use FFI for vips in php. Thanks you for this library. However I'm seeking help. I'm trying to replace direct call with your library.
This is my original code:
exec('cd ' . $this->sourceDirectory . DS . $this->query[0] . DS . $this->query[6]
. ' && ' . $this->vipsExecutable . ' composite "' . implode(' ', $layers) . '" ' . __DIR__ . DS . $filename . ' 7', //VIPS_BLEND_MODE_DEST_OVERIn this library documentation I can see this https://libvips.github.io/php-vips/classes/Jcupitt-Vips-ImageAutodoc.html#method_composite
So based on that I try to call:
$image = Jcupitt\Vips\ImageAutodoc::composite(
$layers,
Jcupitt\Vips\BlendMode::DEST_OVER,
['access' => Jcupitt\Vips\Access::SEQUENTIAL]
);But I get error Fatal error: Uncaught Error: Call to undefined method Jcupitt\Vips\ImageAutodoc::composite()
Of course in this case I fixed paths for $layers, so it's absolute instead of relative.
How I should make it work?
I looked into your library code and I also tried something like this:
$images = [];
foreach ($layers as $layer) {
$images[] = Jcupitt\Vips\Image::newFromFile($layer, ['access' => Jcupitt\Vips\Access::SEQUENTIAL]);
}
array_shift($images)
->composite($images, Jcupitt\Vips\BlendMode::DEST_OVER)
->writeToFile(__DIR__ . DS . $filename);This approach works, but I don't like that I have to create Image instance for each. I would like to follow my original approach where I just provide array of filepaths. Which should work based on the documentation. Any advice?
https://www.libvips.org/API/8.17/type_func.Image.composite.html
Hi @stefanak-michal,
Your second bit of code is correct: you don't pass filenames, you need to pass images, which can come from filenames, sockets, or RAM, as you please. And the static composite function should probably not be declared in autodoc (I'll fix the doc generator), you're suppose to use the hand-written wrapper in Image.php:
https://github.com/libvips/php-vips/blob/master/src/Image.php#L2024-L2061
The underlying problem is that php doesn't let you have static and non-static members with the same name, so you have to pick one of them. Usually (though not always) the non-static interface is more convenient, so php-vips picks that. You'll find similar issues with (for example) Image::bandjoin().
FWIW I think I'd write your example as (untested!):
foreach ($filenames as $filename) {
$layers[] = Vips\Image::newFromFile($filename, ['access' => 'sequential']);
}
$layers[0]
->composite(array_slice($layers, 1), 'over')
->writeToFile($output_filename);Thanks for your reply and the explanation. Therefore I'll try to avoid unavailable static approach in this case.