为什么将CMYK图像转换为sRGB以便在Web上本地显示而不在产品服务器上显示?

时间:2020-06-17 05:00:42

标签: imagemagick imagick image-conversion cmyk srgb

我们的美术师正在提供准备好以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中的“不良”版本却没有。是否可以将其连接到问题的根本原因,如果可以,我该怎么办?我认为exifiptcxmp配置文件是元数据,可以出于测试目的而被忽略。

经过几次尝试和错误,我认为我以正确的顺序接到了transformImageColorspaceprofileImage电话。

我们将不胜感激。

我无法共享完整的src.jpg,但这是其中的一部分(已裁剪为imagemagick convert,以保留其颜色配置文件等)enter image description here

编辑阅读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

0 个答案:

没有答案