使用Imagick显示CMYK黑色

3

当我将文件转换为PDF格式时,绘图层的字体颜色不再是黑色。我尝试添加$image->quantizeImage(255, \Imagick::COLORSPACE_CMYK , 0, TRUE, FALSE);,但会影响质量。

enter image description here

$draw = new ImagickDraw();
$canvas = new Imagick();
$draw->setFillColor("#000000");
$canvas->annotateImage($draw, $x, $y, 0,"Firstname");
$image->compositeImage($canvas,Imagick::COMPOSITE_ATOP,0, 0);

$image->setImageFormat('pdf');  
header('Content-type: application/pdf');
header('Content-Disposition: inline; filename="preview.pdf"');
echo $image->getImagesBlob();


更新 1

我只是想进行一些测试,看看为什么颜色不正确。Imagick 的颜色似乎是倒置的。例如,这段代码会产生:

$im->newImage($imageDimensions['width'], $imageDimensions['height'], new ImagickPixel('white'));

enter image description here

更新 2

我发现字体颜色变成了相反色。我有一个自定义方法可以解决这个问题,但会导致字体偏移。为什么字体颜色会变成白色?要进行测试,请在注释掉的$img之间切换。

    $image = new imagick();
    $img = file_get_contents("https://i.pinimg.com/originals/7c/cb/01/7ccb010d8fddc4bcd84587ef3c34d100.jpg", false);
    //$img = file_get_contents("https://www.footballcomics.co.uk/wp-content/uploads/2020/09/comic_1_page_3_bottom.jpg", false);
        
    $image->readImageBlob($img);
    $draw = new ImagickDraw();
    $canvas = new Imagick();
    $canvas->newPseudoImage(
                600,
                600,
                "canvas:none"
            );
    $draw->setFillColor("#000000");
    $draw->setFontSize( 26);
    //$draw->setFont(plugin_dir_path( __FILE__ ) . './assets/fonts/aAntiCorona.ttf');
    $canvas->annotateImage($draw, 300, 300, 0,"Firstname");
    $image->compositeImage($canvas,Imagick::COMPOSITE_ATOP,0, 0);
    
    $image->setImageFormat('pdf');  
    header('Content-type: application/pdf');
    header('Content-Disposition: inline; filename="preview.pdf"');
    echo $image->getImagesBlob();

更新3

我尝试为Imagick添加配置文件,相信我在正确的轨道上。但仍未能正确显示。

 $icc_cmyk = file_get_contents(plugin_dir_path( '/JapanColor2001Coated.icc');
            $canvas->profileImage('icc', $icc_cmyk);

更新4 运行以下代码将使您可以看到名称的颜色不同。需要将其与图像中的其他黑色文本匹配。

$image = new imagick();
    //$img = file_get_contents("https://i.pinimg.com/originals/7c/cb/01/7ccb010d8fddc4bcd84587ef3c34d100.jpg", false);
    $img = file_get_contents("https://www.footballcomics.co.uk/wp-content/uploads/2020/09/comic_1_page_3_top.tif", false);

    $image->readImageBlob($img);
    $image->setImageColorspace(Imagick::COLORSPACE_CMYK);
    $imageDimensions = $image->getImageGeometry();
    $draw = new ImagickDraw();
    //$draw->setImageColorspace(Imagick::COLORSPACE_CMYK);
    $canvas = new Imagick();
    $canvas->newPseudoImage(
                $imageDimensions['width'],
                $imageDimensions['height'],
                "canvas:none"
            );
    $canvas->setImageColorspace(Imagick::COLORSPACE_CMYK);
    $fillColor = new \ImagickPixel();    
    $fillColor->setColor('cmyk(0%,0%,0%,100%');
    $draw->setFillColor($fillColor);
    $draw->setFontSize( 26);
    //$draw->setFont(plugin_dir_path( __FILE__ ) . './assets/fonts/aAntiCorona.ttf');
    $canvas->annotateImage($draw, 45, 89, 0,"Firstname");
    $canvas->transformImageColorspace(Imagick::COLORSPACE_CMYK);
    $image->compositeImage($canvas,Imagick::COMPOSITE_ATOP,0, 0);
    
    $image->setImageFormat('pdf');  
    header('Content-type: application/pdf');
    header('Content-Disposition: inline; filename="preview.pdf"');
    echo $image->getImagesBlob();

1
我不知道你确切的问题是什么,但根据颜色配置文件,CMYK(0,0,0,100)不对应于RGB(0,0,0)。如果您在屏幕上查看任何内容,它始终是RGB,即使文档显示为CMYK,因为监视器是RGB。 - Chris Haas
谢谢,是的,它似乎会产生两种相隔1像素的不同颜色。你可以在图片中非常模糊地看到它们。这肯定与imagickdraw和PDF行为有关,因为new Imagick();可以正确显示黑色。 - Bish25
@ChrisHaas,我今天大部分时间都在研究这个问题,发现CMYK(60, 60, 60, 100)可以得到深黑色。我还尝试添加了一个配置文件,但没有成功。如果PDF显示有误,打印出来的效果是否还能正常呢? - Bish25
很抱歉,我无法对你的问题给出一个好的答案。我有很多关于PDF和打印的知识,但是我不太了解imagick。然而,如果你有一个针对CMYK设备的输出意图,并且你在该颜色空间中执行所有操作,并且你的所有资产都在该颜色空间中,那么你应该没问题。你看过setImageColorspace吗?此外,你可能可以在CMYK中创建图像,然后将其导出到RGB,将颜色空间更改为类似sRGB的东西。 - Chris Haas
如果您想要一个PDF文件,为什么不使用PDF库(例如FPDF),将图像作为背景并在其上放置文本呢?这样字体颜色将被定义为RGB而不是CMYK。此外,由于PDF字体是基于矢量的,因此您将获得更好的文本质量。 - Olivier
1个回答

0

在合成画布图像之前,您不需要也不应该将其设置为CMYK。

实际上,我不知道底层发生了什么,但我认为正在尝试将包含透明度的RGB图像转换为CMYK是一件愚蠢的事情,因此ImageMagick假定您只想将画布图像视为已经是CMYK,因此颜色从RGBA映射(但不转换)到CMYK。

然而,ImageMagick理解将包含透明度的图像合成到CMYK图像上是一件明智的事情,因此它支持将RGBA图像合成到CMYK上,并同时进行适当的转换。

无论内部实际发生了什么,这段代码似乎可以正常工作:

<?php

$image = new Imagick();
$img = file_get_contents("second.tif", false);

$image->readImageBlob($img);

$imageDimensions = $image->getImageGeometry();
$draw = new ImagickDraw();

$canvas = new Imagick();
$canvas->newPseudoImage(
    $imageDimensions['width'],
    $imageDimensions['height'],
    "canvas:none"
);

$fillColor = new \ImagickPixel();
$fillColor->setColor('black');
$draw->setFillColor($fillColor);
$draw->setFontSize( 26);

$canvas->annotateImage($draw, 45, 89, 0,"Firstname");
$canvas->transformImageColorspace(Imagick::COLORSPACE_CMYK);
$image->compositeImage($canvas,Imagick::COMPOSITE_ATOP,0, 0);

$image->setImageFormat('pdf');
$image->writeImages(__DIR__ . "working.pdf", false);


1
setColor() 行中发现了一个打字错误。缺少 )。根据官方文档,百分比应该被省略。 - Raptor
谢谢,实际上黑色可能更合适,因为这是一张RGB图像。 - Danack

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接