Search code examples
phpimagemagickcolor-profile

PHP Imagemagick convert greyscale to RGB


I made a tool where people can upload photos and modify them, including desaturation, resulting in a greyscale image. I generate the final image using PHP's GD library.

When printing these images the colors appear wrong so using Image Magick I add a color profile.

This works great except for images that have been greyscaled. The color profile gets added, but when I open the image in Photoshop, it says "The embedded ICC profile cannot be used because the ICC profile is invalid. Ignoring the profile". In Photoshop the image is set to Greyscale rather than RGB, hence the attached RGB profile is wrong. I need it to be RGB.

I'm using the following code to add all the possible information in an attempt to make the image RGB:

<?php
$i = new Imagick();
$i->readimage('image.jpg');
$i->setimagetype(Imagick::IMGTYPE_TRUECOLOR);
$i->setimagecolorspace(Imagick::COLORSPACE_RGB);
$i->profileimage('icc', file_get_contents('AdobeRGB1998.icc'));
$i->writeimage($d);
$i->destroy();
?>

Does anyone know how to successfully set the image to RGB and attach the profile?

I did try the different methods and combinations for 'setImageProfile' and 'profileImage', also for colorspace and imagetype, but the result is always the same.


Solution

  • This worked for me to have it recognized as a truecolor image. Assuming $img is the Imagick object containing the greyscaled image, I check if it is indeed greyscale and then edit 1 random pixel and modify its red value by adding or substracting 5 values, depending on red being greater than 5 or not.

    <?php
    if ($img->getImageType() == Imagick::IMGTYPE_GRAYSCALE)
    {
        // Get the image dimensions
        $dim = $img->getimagegeometry();
    
        // Pick a random pixel
        $x = rand(0, $dim['width']-1);
        $y = rand(0, $dim['height']-1);
    
        // Define our marge
        $marge = 5;
        //$x = 0;
        //$y = 0;
    
        // Debug info
        echo "\r\nTransform greyscale to true color\r\n";
        echo "Pixel [$x,$y]\n";
    
        // Get the pixel from the image and get its color value
        $pixel = $img->getimagepixelcolor($x, $x);
        $color = $pixel->getcolor();
        array_pop($color); // remove alpha value
    
        // Determine old color for debug
        $oldColor   = 'rgb(' . implode(',',$color) . ')';
        // Set new red value
        $color['r'] = $color['r'] >= $marge ? $color['r']-$marge : $color['r'] + $marge;
        // Build new color string
        $newColor   = 'rgb(' . implode(',',$color) . ')';
    
        // Set the pixel's new color value
        $pixel->setcolor($newColor);
    
        echo "$oldColor -> $newColor\r\n\r\n";
    
        // Draw the pixel on the image using an ImagickDraw object on the given coordinates
        $draw = new ImagickDraw();
        $draw->setfillcolor($pixel);
        $draw->point($x, $y);
        $img->drawimage($draw);
    
        // Done, 
        unset($draw, $pixel);
    }
    // Do other stuff with $img here
    ?>
    

    Hope this helps anyone in the future.