Create a true grayscale PNG in PHP
Asked Answered
C

1

6

I need to create a grayscale image in PHP. I am not talking about an indexed image with grayscale values in its palette, but about a TRUE grayscale image. The difference is in the 26th byte of the PNG (color type):

0 - greyscale  <-- THIS IS WHAT I NEED
2 - RGB
3 - RGB with palette
4 - greyscale + alpha
6 - RGB + alpha

(See How to check a PNG for grayscale/alpha color type? for details)

I tried imagefilter($im, IMG_FILTER_GRAYSCALE); as well as imagetruecolortopalette($im, false, 255); but all I get are either RGB grayscale images (color type 2) or RGB palette images with a grayscale palette (color type 3). I also tried to initialize the image with imagecreate() instead of imagecreatetruecolor() but again this only leads to a palette image.

Is there any way to create a color type 0 grayscale PNG with PHP's GD functions (or any other functions in PHP)?

Here are some samples of different grayscale images to show what I mean. They all look the same, but if you open them in PhotoShop and look at the Image -> Mode setting, you see the difference. Also a hex editor will reveal the difference in the 26th byte:

RGB RGB, color type 2, 3149 bytes
RGB palette RGB palette, color type 3, 3971 bytes
True Grayscale Image True grayscale image, color type 0, 1105 bytes <-- THIS IS WHAT I NEED


UPDATE 01:

Here is the basic code that I use to create the PNGs. Commented lines are alternatives that I have tried:

//$im = imagecreate($image_size, $image_size);
$im = imagecreatetruecolor($image_size, $image_size);

//imagefilter($im, IMG_FILTER_GRAYSCALE);
//imagetruecolortopalette($im, false, 255);

imagepng($im, $imgPathName);
imagedestroy($im);
Cystocarp answered 17/9, 2012 at 14:24 Comment(7)
how does your code look so far?Quickly
@Breezer: See "UPDATE 01" in my OP.Cystocarp
I'm guessing you're looking for php.net/manual/en/function.imagecolorallocate.php I think this tutorial will help you along the way, php.about.com/od/gdlibrary/ss/grayscale_gd.htmQuickly
with imagecolorallocate you define what colors is to be used, the palette basicallyQuickly
Sorry Breezer, but you are way off. As I clearly stated I do NOT want to create a palette image, but an 8-bit grayscale image. It has nothing to do with palettes. It is similar to an RGB image but with only one color channel instead of three channels.Cystocarp
hmmm perhaps php.net/manual/en/function.imagecolorset.php?Quickly
Breezer, if you read the word "palette" in any of your researches, just drop it. I have read this all. As said: My problem has nothing to do with palettes.Cystocarp
T
6

GD library does not support converting to a "true" grayscale. It only supports RGB and TrueColor*.

Is there any way to create a color type 0 grayscale PNG with PHP's GD functions (or any other functions in PHP)?

ImageMagick is what you are looking for.

$im = new Imagick();
$im->readImage('file.png');
$im->setImageType(Imagick::IMGTYPE_GRAYSCALE);
$im->writeImage('file.gray.png');
Tuchun answered 17/9, 2012 at 18:3 Comment(3)
@Xeoncross from the source bitbucket.org/pierrejoye/gd-libgd/src - only supports RGB and TrueColor* output.Tuchun
@h0tw1r3: That's it - thank you! As a side note: I have sworn to never use ImageMagick again as long as I have access to GraphicsMagick on the target machine. Fortunately h0tw1r3's code will work perfectly with GM, if you replace Imagick by Gmagick (and install the GraphicsMagick PHP extension).Cystocarp
I found that the Gmagick and Imagick PHP extensions are extremely hard to find as precompiled Windows versions. So just in case any reader of this thread will look for a Windows solution: Better use a shell call to IM/GM executables like this: exec('gm mogrify -type grayscale "C:/path/to/your/file.png"');Cystocarp

© 2022 - 2024 — McMap. All rights reserved.