我们的美术师正在提供准备好以CMYK颜色空间JPG格式打印的图像,该图像适合打印。我正在转换这些内容以在网络上显示。我了解“最好”的做法是将src.jpg转换为sRGB色彩空间。我已经尝试过使用convert
的命令行和使用transformImageColorspace()
的Imagick方法,都发现它在我的本地计算机(Fedora 32 Linux)上可以正常工作,但在生产服务器(CentOS 7.3 Linux)上却不能正常工作
我们已经使用命令行convert
在生产环境中运行了该流程几年了,但是最近我们加强了安全性,并从PHP禁用了exec
,所以我试图做到这一点通过Imagick绑定进行处理,但是生成的图像无法正确显示。我不知道是否正确地应用了ICC颜色配置文件,或者向sRGB的转换有问题,或者发生了什么其他情况。
本地计算机: 版本:ImageMagick 6.9.10-86 Q16 x86_64 2020-01-31 https://imagemagick.org
产品服务器: 版本:ImageMagick 6.9.11-19 Q16 x86_64 2020-06-15 https://imagemagick.org
两台机器都显示'lcms'在Delegates (built-in)
列表中,这是可能会引起麻烦但看起来不错的一件事。
源图像:CMYK格式的src.jpg,主要是灰色/白色图像。
在Gnome的Image Viewer中加载该图像会显示不正确的颜色,淡蓝色,但这是因为Gnome无法正确处理CMYK。将相同的图像加载到GIMP中会自动将其转换为sRGB,并正确显示灰色/白色。我的目的是生成输出文件src_srgb.jpg,该文件在加载到Image Viewer中时显示为灰色/白色(因此显然是简单的RGB配置文件图像)。
源代码:
class Logger {
public function log ($str) {
echo $str . "\n";
}
}
$l = new Logger();
$master_filename_abs = 'srgb/src.jpg';
$icc_profile_file = 'AdobeRGB1998.icc';
$pathinfo = pathinfo($master_filename_abs);
// e.g. turn mickey.jpg into mickey_srgb.jpg
$preview_filename = $pathinfo['filename'] . '_srgb.' . $pathinfo['extension'];
$preview_filename_abs = $pathinfo['dirname'] . '/' . $preview_filename;
$useCmdLine = false; // use cmd line 'convert', or Imagick?
try {
if ($useCmdLine) {
$cmd = 'convert "' . $master_filename_abs . '" -verbose' .
' -profile "' . $icc_profile_file . '"' .
' -colorspace srgb' .
' -resize 800 "' . $preview_filename_abs . '" 2>&1';
$l->log('executing "' . $cmd . '"...');
exec($cmd, $output, $return_var);
$l->log("exec returned $return_var with " . count($output) . ' lines of output:' .
join("\n", $output));
} else {
$master_img = new Imagick();
$master_img->readImage($master_filename_abs);
$icc_profile_contents = file_get_contents($icc_profile_file);
$l->log('About to profileImage()...');
$r = $master_img->profileImage('icc', $icc_profile_contents);
$l->log("profileImage returned $r " . ($r == TRUE ? 'true' : 'false'));
$space = $master_img->getImageColorspace();
$l->log("Colorspace starts as $space, CMYK is " . Imagick::COLORSPACE_CMYK);
$r = $master_img->transformImageColorspace(imagick::COLORSPACE_SRGB);
$l->log("transformImageColorspace returned $r " . ($r == TRUE ? 'true' : 'false'));
$space = $master_img->getImageColorspace();
$l->log("Colorspace after conversion is $space, SRGB is " . Imagick::COLORSPACE_SRGB);
$master_img->scaleImage(800, 0);
$l->log('Saving RGB profile version to ' . $preview_filename_abs);
$master_img->writeImage($preview_filename_abs);
}
} catch (Exception $ex) {
$l->log('Caught ' . $ex);
}
先决条件:src.jpg应位于“ srgb”目录中,而AdobeRGB1998.icc配置文件应位于当前目录中。
如您所见,在脚本中既有命令行尝试,也有Imagick尝试,其中有一个$useCmdLine
布尔值在它们之间切换。
在本地计算机上的结果:src_srgb.jpg已创建,看起来不错。颜色与src.jpg图片匹配。
$ / opt / remi / php71 / root / bin / php imagick_srgb.php 关于profileImage()... profileImage返回1是 色彩空间从13开始,CMYK为12 transformImageColorspace返回1 true 转换后的色彩空间为13,SRGB为13 将RGB配置文件版本保存到srgb / src_srgb.jpg
identify -verbose srgb/src_srgb.jpg
显示:
Colorspace: sRGB
Type: TrueColor
...
Profiles:
Profile-8bim: 6694 bytes
Profile-exif: 4617 bytes
Profile-icc: 560 bytes
Profile-iptc: 17 bytes
unknown[2,0]:
Image Name[2,5]: Print
Profile-xmp: 16695 bytes
产品服务器上的结果:src_srgb.jpg已创建,但看起来偏蓝。
$ /opt/cpanel/ea-php73/root/usr/bin/php imagick_srgb.php
About to profileImage() with 1 bytes of profile data...
profileImage returned 1 true
Colorspace starts as 12, CMYK is 12
transformImageColorspace returned 1 true
Colorspace after conversion is 13, SRGB is 13
Saving RGB profile version to srgb/src_srgb.jpg
identify -verbose srgb/src_srgb.jpg
显示:
Colorspace: sRGB
Type: TrueColor
...
Profiles:
Profile-8bim: 6694 bytes
Profile-exif: 4617 bytes
Profile-iptc: 17 bytes
unknown[2,0]:
Image Name[2,5]: Print
Profile-xmp: 16695 bytes
我在配置文件列表中看到本地计算机上的“良好”版本在Profile-icc
中,而prod中的“不良”版本却没有。是否可以将其连接到问题的根本原因,如果可以,我该怎么办?我认为exif
,iptc
和xmp
配置文件是元数据,可以出于测试目的而被忽略。
经过几次尝试和错误,我认为我以正确的顺序接到了transformImageColorspace
和profileImage
电话。
我们将不胜感激。
我无法共享完整的src.jpg,但这是其中的一部分(已裁剪为imagemagick convert
,以保留其颜色配置文件等)
编辑阅读PHP Imagick won't add ICC color profile,我想证明生产服务器存在lcms:
$ convert -list configure | grep DELEGATES
DELEGATES bzlib djvu mpeg fftw fontconfig freetype gslib heic jbig jng jpeg lcms lzma openexr openjp2 pango png raqm raw rsvg tiff webp wmf x xml zlib zstd
DELEGATES bzlib cairo djvu fftw fontconfig freetype gslib gvc heic jbig jng jp2 jpeg lcms ltdl lzma openexr pangocairo png ps raqm raw rsvg tiff webp wmf x xml zlib
$ rpm -qa | grep cms
lcms2-devel-2.6-3.el7.x86_64
lcms2-2.6-3.el7.x86_64
编辑2 这两个系统上的imagemagick有点奇怪。我的本地计算机在src.jpg上报告了一个icc配置文件,但是对于完全相同的图像却没有生产。我尝试将自己的附件下载为SO.jpg进行检查,然后将其复制到产品中,并比较identify -verbose SO.jpg
的输出:
$ diff so_local so_prod
1c1,2
< Image: SO.jpg
---
> Image:
> Filename: srgb/SO.jpg
12c13
< Endianess: Undefined
---
> Endianness: Undefined
83,84d83
< Profiles:
< Profile-icc: 557168 bytes
86,89c85,86
< date:create: 2020-06-17T06:14:10+00:00
< date:modify: 2020-06-17T06:14:10+00:00
< icc:copyright: Copyright 2000 Adobe Systems, Inc.
< icc:description: U.S. Web Coated (SWOP) v2
---
> date:create: 2020-06-17T06:14:59+00:00
> date:modify: 2020-06-17T06:14:59+00:00
94c91
< filename: SO.jpg
---
> filename: srgb/SO.jpg
99c96
< Pixels per second: 25.3889MB
---
> Pixels per second: 27.3785MB
102c99
< Version: ImageMagick 6.9.10-86 Q16 x86_64 2020-01-31 https://imagemagick.org
---
> Version: ImageMagick 6.9.11-19 Q16 x86_64 2020-06-15 https://imagemagick.org
这真的让我很恶心,几乎不了解imagemagick。我将研究在生产环境中将ImageMagick软件包降级以匹配本地软件包,但我们正在生产服务器上进入白天运行时间,因此我可能无法。
编辑3 回到我们过去的工作,它似乎已经在2020年6月1日停止工作,并且那天我看到ImageMagick-6.9.11.14-1.el7.remi.x86_64
已升级为ImageMagick-6.9.11.16-1.el7.remi.x86_64
(以及-libs
和-devel
软件包)。因此,似乎在6.9.11.14-1和6.9.11.16-1之间引入了这一重大更改。我们从中获得的remi repo似乎只有两个最新版本,分别是6.9.11.18-1和6.9.11.19-1,降级到6.9.11.18-1并不能解决我的问题。
编辑4 可能已使用PHP Imagick绑定成功完成了转换。在https://www.imagemagick.org/discourse-server/viewtopic.php?p=67114#p67114处的注释中,“您应该先定义CMYK颜色空间,应用所需的任何操作,然后定义RGB颜色空间”,并带有示例convert -colorspace CMYK mona_lisa.cmyk.jpg -modulate 110 -colorspace RGB monalisa_rgb.jpg
..因此,我尝试了一下(首先将配置文件设置为null以删除任何现有配置文件):
$r = $master_img->profileImage('icc', null);
$r = $master_img->profileImage('icc', file_get_contents($cmyk_icc_profile_file));
$r = $master_img->profileImage('icc', file_get_contents($srgb_icc_profile_file));
$r = $master_img->transformImageColorspace(imagick::COLORSPACE_SRGB);
令我非常惊讶的是,在prod上使用本地版本6.9.10-86和旧版本6.9.11-14,输出文件在Gnome Image Viewer和Web浏览器中显示正确,所以我认为这是一个解决的问题。我仍然不知道为什么最新版本的ImageMagick 6.9.11-19似乎无法正常工作,会一直保持下去。
编辑5 ImageMagick团队接受并修复了我的错误报告:) https://github.com/ImageMagick/ImageMagick6/issues/83