libvips/php-vips

Unable to Write AVIF to Buffer Using .avif Suffix

freshleafmedia opened this issue ยท 2 comments

If I try to re-encode an image from JPEG to AVIF everything works as expected:

$image = \Jcupitt\Vips\Image::newFromFile('path/to/image.jpg');
$image->writeToFile('path/to/image.avif');

However if I try to write the AVIF image to a buffer I get an error:

$image = \Jcupitt\Vips\Image::newFromFile('path/to/image.jpg');
$buffer = $image->writeToBuffer('.avif');
libvips error: VipsForeignSave: ".avif" is not a known buffer format

The difference seems to be in the vips_foreign_find methods:

FFI::vips()->vips_foreign_find_save('.avif'); // "VipsForeignSaveHeifFile"
FFI::vips()->vips_foreign_find_save_buffer('.avif'); // null

I can get it to do it if I use the following workaround:

$image = \Jcupitt\Vips\Image::newFromFile('path/to/image.jpg');
$buffer = $image->writeToBuffer('.heif', ['compression' => 'av1'])

Am I doing something wrong or is this expected behaviour?

Hello @freshleafmedia,

This PR should fix your problem:

#191

It needs merging, I've been too busy to help sort it out, unfortunately. Maybe this weekend.

Background: libvips used to support file and memory read and write. In 8.10 we added a new virtual IO system based on two new classes called source and target that lets you read and write from any IO-like object. For example, you can do this:

$ vips copy k2.jpg .avif | cat > x.avif
$ file x.avif
x.avif: ISO Media, AVIF Image

Very handy for things like S3 -- you can write directly to a bucket over a pipe.

The old buffer/file API has been mostly moved onto this new thing, but there are a few holes, like the one you've found. Adding proper source / target support to php-vips would fix these problems, and add useful new functionality.

I've made a PR for this: #207

Any testing very welcome! I'll close this issue -- any discussion should continue on that PR.