简体   繁体   中英

Convert CMYK PDF to SRGB JPG using PHP and Imagick

I'm trying to convert the first page of PDF documents to a JPEG using Imagick and PHP. As long as the colorspace of the PDF is SRGB, conversion succeeds and the resulting images have correct colors. However, if the PDF has a CMYK colorspace, after conversion, the image colors are off (much brighter or darker).

I'm currently using the following software:

  • PHP 7.4.3
  • ImageMagick 6.9.10-23 Q16 x86_64 20190101 (deb package)
  • Ghostscript 9.50 (2019-10-15)

I'm working on WSL2 on Windows 10.

My test PDF can be found here .

Because I was not happy with the resulting conversions, I firstly tried to see if it is possible to do a successful conversion using Imagick cli. After lots of trial and error, I found that the following command yielded the best result:

convert -density 300 -colorspace srgb input.pdf[0] -layers flatten -strip output.jpg

Result:

在此处输入图片说明

I then rewrote the command to PHP:

$input = 'input.pdf';
$output = 'output.pdf';
$image = new Imagick();
$image->setResolution(300, 300);
$image->readImage("{$input}[0]");
$image->transformImageColorspace(Imagick::COLORSPACE_SRGB);
$image = $image->mergeImageLayers(Imagick::LAYERMETHOD_FLATTEN);
$image->setImageFormat('jpeg');
$image->stripImage();
$image->writeImage($output);
$image->destroy();

Result:

在此处输入图片说明

The result of the PHP code is not the same as the result of the CLI version and the original PDF. The result is the same as if I would run te following CLI command:

convert -density 300 input.pdf[0] -colorspace srgb -layers flatten -strip output.jpg

The command looks almost the same, however the transforming of the color space happens later.

My question is: what step do I miss in my PHP code to achieve the same result as the command

convert -density 300 -colorspace srgb input.pdf[0] -layers flatten -strip output.jpg

Additional information: I also tried using color profiles to do the colorspace transformations. Instead of

$image->transformImageColorspace(Imagick::COLORSPACE_SRGB);

I used

$cmyk = file_get_contents('USWebCoatedSWOP.icc');
$rgb = file_get_contents('sRGB_v4_ICC_preference.icc');
$image->profileImage('icc', $cmyk);
$image->profileImage('icc', $rgb);

Besides these two profiles, I also tried combinations of other CMYK (CoatedFOGRA39, JapanColor2001Coated...) and SRGB (AdobeRGB1998, AppleRGB, sRGB_v4_ICC_preference_displayclass...) profiles.

However, I couldn't find a profile combination that came close to the result of the CLI output and the original PDF file.

Thanks to @fmw42, I was able to fix my issue. To fix it, set the color space using setColorSpace() before reading in the pdf.

$input = 'input.pdf';
$output = 'output.pdf';

$image = new Imagick();

$image->setResolution(300, 300);
$image->setColorSpace(Imagick::COLORSPACE_SRGB); // Add this line

$image->readImage("{$input}[0]");

// $image->transformImageColorspace(Imagick::COLORSPACE_SRGB); // You don't need this line
$image = $image->mergeImageLayers(Imagick::LAYERMETHOD_FLATTEN);

$image->setImageFormat('jpeg');
$image->stripImage();
$image->writeImage($output);

$image->destroy();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM