libvips/php-vips

Unable to strip metadata with keep

hugopeek opened this issue · 6 comments

Hi! Thanks, first of all, for this amazing library. It saved my ass when the Squoosh project was (rather quietly) abandoned.

I'm using PHP now to resize the images, and for web-facing thumbnails I'm trying to remove the EXIF data.. But I'm having some difficulties figuring it out.

$image = Vips\Image::thumbnail($srcPath, $width, ['height' => $height]);
$image
    ->jpegsave($tempFile, [
        'Q' => $quality,
        'keep' => ['none'],
    ]
);

It seems to be expecting an array, but whatever I feed it: nothing gets stripped.

I did stumble upon the 'strip' property just now, and that takes care of it, albeit bluntly. What am I missing that I can't use the more selective 'keep' method? I tried using the 2 in conjuction, but that only seems to bypass strip altogether.

Hmm. Without the array, it does strip metadata.. But it always seems to be all of it, regardless of using 'keep' => 'all' or a similar setting.

Hi @hugopeek, we added flag parsing to the string -> enum converter to avoid having to change any of the language bindings. Try 'keep' => 'exif|icc'.

I made a test program:

require dirname(__DIR__) . '/vendor/autoload.php';

use Jcupitt\Vips;

function printMetadata($im) {
    foreach ($im->getFields() as &$name) {
        $value = $im->get($name);
        if (str_ends_with($name, "-data")) { 
            $len = strlen($value);
            $value = "<$len bytes of binary data>";
        }
        echo "   $name: $value\n";
    }
}

$im = Vips\Image::newFromFile($argv[1]);
echo "$argv[1]\n";
printMetadata($im);

$buf = $im->tiffsave_buffer(['keep' => 'icc']);
$im2 = Vips\Image::newFromBuffer($buf, "");
echo "\nafter keep => icc\n";
printMetadata($im2);

$buf = $im->tiffsave_buffer(['keep' => 'exif:icc']);
$im2 = Vips\Image::newFromBuffer($buf, "");
echo "\nafter keep => exif:icc\n";
printMetadata($im2);

But it doesn't seem to work! I'll investigate.

There are some changes needed for php-vips to support symbolic flag values, I'll make a PR.

In the meantime, you can always pass an int, for example:

abstract class ForeignKeep
{
    const NONE = 0;
    const EXIF = 1;
    const XMP = 2;
    const IPTC = 4;
    const ICC = 8;
    const OTHER = 16;
    const ALL = 31;
}

$buf = $im->tiffsave_buffer(['keep' => ForeignKeep.EXIF | ForeignKeep.ICC]);

Hi @jcupitt, thanks for the swift reply!

Ah, so it's an enum.. That's still relatively new for us PHP folk :) Using the int numbers seems to work without issue in my own code, but not in your example. Anyway, thanks a bunch for the quick workaround!

It should be fixed in master, and I added an example:

https://github.com/libvips/php-vips/blob/master/examples/keep.php

Thanks for reporting this!