thumbnail_image converts CMYK image to RGB
Hey, thanks so much for this project! It has been a pleasure to use so far.
I'm finding that these lines of code are outputting an RGB image, when my source is a CMYK with an embedded profile:
$image = VipsImage::newFromFile('input.jpeg');
$image = $image->thumbnail_image(1000);
$image->writeToFile('output.jpeg', [ 'Q' => 95 ]);
If I remove the thumbnail_image call, the output is CMYK. It looks like thumbnail_image may have import-profile and export-profile options? But I'm not sure what they do, or how to get the profile from the image. Is there some way to tell it to just keep the image in whatever color format it is in? RGB should stay RGB, and CMYK should stay CMYK.
Hi @AdamGaskins,
Yes, you need to set the output profile. By default, libvips will use an sRGB output profile, since CMYK profiles can be so large (eg. 500kb is not uncommon), and of course most people want thumbnails to be small.
You can do something like this:
$image = Vips\Image::new_from_file("something.jpg");
if ($image->interpretation == "cmyk") {
$profile = "cmyk";
}
else if ($image->interpretation = "srgb") {
$profile = "srgb";
}
else {
unknown profile error
}
$thumbnail = Vips\Image::thumbnail("something.jpg", 1000, [
"export-profile" => $profile
]);
Don't use thumbnail_image, it's only for emergencies. Plain thumbnail will be many times faster.
The main docs are here, in case you didn't see them:
https://www.libvips.org/API/current/libvips-resample.html#vips-thumbnail
Thanks for the response!! Here is the code I'm using based on yours:
$image = VipsImage::newFromFile($input);
$profile = 'srgb';
if ($image->interpretation == 'cmyk') {
$profile = 'cmyk';
}
$image = \Jcupitt\Vips\Image::thumbnail($input, 1000, [ 'export-profile' => $profile ]);
$image->writeToFile($output, [ 'Q' => 95 ]);
It works fine for RGB images, but CMYK gives this warning:
(process:51830): VIPS-WARNING **: 08:49:44.160: profile incompatible with image
The output file is indeed in CMYK, but it has an incorrect profile and colors. (Here is the image I'm using)
In messing around I weirdly found this code seems to work, but I may be completely off and I would definitely prefer to use thumbnail since that seems to be the intended way:
$image = VipsImage::newFromFile('input.jpeg');
$image = $image->icc_import();
$image = $image->thumbnail_image($pixelSize);
$image = $image->icc_export();
$image->writeToFile('output.jpeg', [ 'Q' => 95 ]);
Oooof, I think you've found a bug in thumbnail. I'll investigate.
OK, I think I fixed it. This improvement will be in 8.12.3, thanks for the report!
I now see:
$ vipsheader cmyk5.jpg
cmyk5.jpg: 3654x4577 uchar, 4 bands, cmyk, jpegload
$ vipsthumbnail cmyk5.jpg --export-profile cmyk
$ vipsheader tn_cmyk5.jpg
tn_cmyk5.jpg: 102x128 uchar, 4 bands, cmyk, jpegload
ie. the thumbnail is cmyk in this case.
Your embedded profile is 500kb, so it's a huge thumbnail image, which might not be what you want.
Ahh okay, thank you so much! Really impressed by the quick response and fix!!
Your embedded profile is 500kb, so it's a huge thumbnail image, which might not be what you want.
Yeah... that's what I told the user too, but they insisted they need the profile embedded 🤷🏻♂️