7

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.

Nilesh
  • 1,047
  • 1
  • 12
  • 20

2 Answers2

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

enter image description here

(Destination: pfc8bit.png) CONVERTED PNG IMAGE (8-bit)

enter image description here

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):

enter image description here

pngquant supports alpha transparency very well.

Kornel
  • 97,764
  • 37
  • 219
  • 309