Display CMYK black using Imagick

Viewed 241

I am having the issue when converting to pdf the draw layer font colour is no longer black. I have tried adding this $image->quantizeImage(255, \Imagick::COLORSPACE_CMYK , 0, TRUE, FALSE); however, the quality is effected.

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


update 1

I'm just trying to do some tests to see why the colour is incorrect. The Imagick colours appear to be inverted. For example, this code produces

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

enter image description here

Update 2 I have discovered that the font colour becomes inverted. I do have a custom method that does inverse this. but causes the font to be off. Why does the font colour change to white. To test switch between the commented out $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();

Update 3

I have tried adding profiles to the Imagick, believe I'm on the right track here. But still not presenting correctly

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

Update 4 Running the code below will allow you to see Firstname be a different shade. Need that to match the other black text from the image.

$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 Answers

You don't need, and shouldn't set the canvas image to CMYK before compositing it.

I actually don't know what is happening under the hood, but I think what is happening is that attempting to convert an RGB image that contains transparency to CMYK is a silly thing to do, and so instead of 'converting' it, ImageMagick assumes you just want to treat that canvas image as CMYK already, and so the colours get mapped (but not transformed) from RGBA to CMYK.

However, ImageMagick is understands that compositing images that contain transparency onto a CMYK image is a sensible thing to do, and so it supports composting RGBA images onto CMYK and doing the appropriate conversion at the same time.

Anyway, regardless of what is actually happening internally, this code appears to work:

<?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);

Related