I want to write a routine which takes PNG image path as parameter and convert that image into 8-bit PNG image. I need to use PHP GD library for this.
Asked
Active
Viewed 9,925 times
7
-
3What is your question? It's nice that you're telling us your TODO list for the day, but that doesn't make it a question. – cweiske Apr 22 '11 at 07:12
-
ImageMagick would be a better option. – Pekka Apr 22 '11 at 07:17
-
1@Znarkus I wasn't sure whether it was possible in GD at all, but @Wh1T3h4Ck5 proved me wrong. – Pekka Apr 22 '11 at 08:25
2 Answers
14
To convert any PNG image to 8-bit PNG use this function, I've just created
function convertPNGto8bitPNG ()
function convertPNGto8bitPNG ($sourcePath, $destPath) {
$srcimage = imagecreatefrompng($sourcePath);
list($width, $height) = getimagesize($sourcePath);
$img = imagecreatetruecolor($width, $height);
$bga = imagecolorallocatealpha($img, 0, 0, 0, 127);
imagecolortransparent($img, $bga);
imagefill($img, 0, 0, $bga);
imagecopy($img, $srcimage, 0, 0, 0, 0, $width, $height);
imagetruecolortopalette($img, false, 255);
imagesavealpha($img, true);
imagepng($img, $destPath);
imagedestroy($img);
}
Parameters
- $sourcePath - Path to source PNG file
- $destPath - Path to destination PNG file
Note
I recommend to make sure that $sourcePath
exists and $destPath
is writable before running this code. Maybe this function won't work with some transparent images.
Usage
convertPNGto8bitPNG ('pfc.png', 'pfc8bit.png');
Example (original -> 8-bit)
(Source: pfc.png) ORIGINAL PNG IMAGE
(Destination: pfc8bit.png) CONVERTED PNG IMAGE (8-bit)
Hope someone finds this helpful.

Wh1T3h4Ck5
- 8,399
- 9
- 59
- 79
-
@Nilesh, I've just tried with few transparent PNG's and it works? Send me a link to transparent PNG you use. – Wh1T3h4Ck5 Apr 22 '11 at 11:52
-
Image that I have used is: http://www.google.co.in/imgres?imgurl=http://www.axdn.com/redist/axmb_logo.png&imgrefurl=http://www.axdn.com/mediabrowser/&usg=__VDQGJObwovhCTh3xFq1XeJSxO8U=&h=300&w=400&sz=87&hl=en&start=0&zoom=1&tbnid=d7PzzB9Ok-gJ2M:&tbnh=155&tbnw=181&ei=DXCxTcOaNILYuAPMrsybBw&prev=/search%3Fq%3Dpng%2Btransparent%2Bimages%26hl%3Den%26biw%3D1280%26bih%3D800%26gbv%3D2%26tbm%3Disch0%2C181&itbs=1&iact=hc&vpx=516&vpy=246&dur=279&hovh=194&hovw=259&tx=150&ty=98&page=1&ndsp=24&ved=1t:429,r:14,s:0&biw=1280&bih=800 – Nilesh Apr 22 '11 at 12:10
-
@Nilesh, YES, you were right... I forgot to set transparent color. Function above now has new body... try it again. – Wh1T3h4Ck5 Apr 22 '11 at 12:25
-
@Wh1T3h4Ck5, Yes, it is working now. But image is not clear yet. I have tried with some other images as well – Nilesh Apr 22 '11 at 12:39
-
@Nilesh, I was researching about this and found that 8-bit PNG is same as GIF because both of them use bit-transparency (don't have alpha channel). Actually, I've found solution to convert any PNG to GIF (transparency, 256 colors) but when I try to convert it to transparent PNG, it turns into 32-bit (I guess, because most of GD functions return 32-bit results). But later I've found that, even 'properties' window says that image I've created this way is 32-bit PNG, Photoshop recognizes them as PNG-8 and those images have actual size of 8-bit PNGs!? Strange behavior... – Wh1T3h4Ck5 Apr 23 '11 at 11:02
-
Unlike GIF, you are able to use alpha transparency with 8-bit PNGs, though there are not many programs that are able to produce them. See http://blogs.sitepoint.com/png8-the-clear-winner/ – Marcel Korpel Apr 25 '11 at 11:08
-
@Marcel - According to that link `It offers GIF-like 1-bit transparency. Pixels are either solid or completely transparent, but never partially see-through`. You can't use alpha transparency against PNG-8 images because it doesn't have alpha level (like e.g. PNG 32-bit). In other words, PNG-8 uses solid color as transparent (exactly what GIF does) – Wh1T3h4Ck5 Apr 25 '11 at 11:35
-
If read one sentence below that point, you read “Although this last point is generally accepted as fact, it isn’t strictly true, and this is the topic we’ll be examining today.” ;-) – Marcel Korpel Apr 25 '11 at 11:37
-
@Marcel, also look [my answer here](http://stackoverflow.com/questions/5766865/rounded-transparent-smooth-corners-using-imagecopyresampled-php-gd/5767092#5767092). You can get full alpha transparency by using PNG 32-bit only (RGBA - Red-Green-Blue-Alpha). – Wh1T3h4Ck5 Apr 25 '11 at 11:39
-
@Marcel, however, thank you for this link, I'll read this complete article and see what can I do about this problem. – Wh1T3h4Ck5 Apr 25 '11 at 11:41
-
So does it mean, it is not possible to create 8-bit transparent png using GD? Thank you guys for all your efforts and your valuable information. – Nilesh Apr 25 '11 at 12:55
-
@Nilesh, It's possible. Now I'm looking for solution to accomplish that. We're talking about bit-transparency vs alpha-transparency and how to get 4-bit transparency inside indexed-palette PNG-8. You could see that transparency works on PNG-8, but that's not expected 'good looking' result. I'm busy at the moment, but I'll try to solve this problem as soon as possible. – Wh1T3h4Ck5 Apr 25 '11 at 13:26
10
Instead of GD library I strongly recommend using pngquant 1.5+ commandline using exec()
or popen()
functions.
GD library has very poor-quality palette generation code.
Same image as in the other answer, same file size as GD library, but converted using pngquant
to merely 100 colors (not even 256):
pngquant supports alpha transparency very well.

Kornel
- 97,764
- 37
- 219
- 309