Преобразование CMYK PDF в SRGB JPG с использованием PHP и Imagick

Я пытаюсь преобразовать первую страницу PDF-документов в JPEG, используя Imagick и PHP. Пока цветовое пространство PDF равно SRGB, преобразование выполняется успешно, и полученные изображения имеют правильные цвета. Однако, если PDF-файл имеет цветовое пространство CMYK, после преобразования цвета изображения отключаются (намного ярче или темнее).

В настоящее время я использую следующее программное обеспечение:

  • PHP 7.4.3
  • ImageMagick 6.9.10-23 Q16 x86_64 20190101 (пакет deb)
  • Ghostscript 9.50 (15.10.2019)

Я работаю над WSL2 в Windows 10.

Мой тестовый PDF-файл можно найти по адресу здесь.

Поскольку я не был доволен полученными преобразованиями, я сначала попытался посмотреть, можно ли выполнить успешное преобразование с помощью Imagick cli. После множества проб и ошибок я обнаружил, что следующая команда дала лучший результат:

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

Результат:

введите здесь описание изображения

Затем я переписал команду на 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();

Результат:

введите здесь описание изображения

Результат кода PHP не совпадает с результатом версии CLI и исходного PDF. Результат такой же, как если бы я запустил следующую команду CLI:

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

Команда выглядит почти так же, однако трансформация цветового пространства происходит позже.

Мой вопрос: какой шаг я пропустил в своем PHP-коде, чтобы добиться того же результата, что и команда

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

Дополнительная информация: я также пытался использовать цветовые профили для преобразования цветового пространства. Вместо

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

я использовал

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

Помимо этих двух профилей, я также пробовал комбинации других профилей CMYK (CoatedFOGRA39, JapanColor2001Coated...) и SRGB (AdobeRGB1998, AppleRGB, sRGB_v4_ICC_preference_displayclass...).

Однако мне не удалось найти комбинацию профилей, которая была бы близка к результату вывода CLI и исходному файлу PDF.


person Tomasz Nguyen    schedule 30.10.2020    source источник
comment
Вам нужно изменить цветовое пространство перед чтением входного PDF-файла, как и в случае с плотностью. ImageMagick использует Ghostscript для чтения PDF-файлов, но не работает с CMYK с альфа-каналом. Таким образом, вы должны читать в формате PDF и при этом конвертировать в sRGB.   -  person fmw42    schedule 30.10.2020
comment
@fmw42 Спасибо! Я попытался установить цветовое пространство перед чтением PDF-файла с помощью $image->setImageColorSpace(Imagick::COLORSPACE_SRGB);, но это не сработало. Теперь я вижу, что пропустил метод setColorSpace(), и преобразование с помощью этого метода работает как положено. Еще раз спасибо!   -  person Tomasz Nguyen    schedule 30.10.2020


Ответы (1)


Благодаря @fmw42 я смог решить свою проблему. Чтобы исправить это, установите цветовое пространство с помощью setColorSpace() перед чтением в формате 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();
person Tomasz Nguyen    schedule 30.10.2020