phppdfimagickcmyksrgb

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:

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:

enter image description here

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:

enter image description here

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.


Solution

  • 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();