4

I am using GD to output an image that is a truecolor+alpha channel PNG file using imagepng just fine. However, I would like to have the ability to also output an ie6-compatible 256-color PNG as well. According to the official documentation for imagetruecolortopalette:

The code has been modified to preserve as much alpha channel information as possible in the resulting palette, in addition to preserving colors as well as possible.

However, I am finding that the results of this function do not properly preserve any transparency at all. I used this firefox image with text superimposed on top of it as a test, and all the function did was give me a white background and a weird dark blue border. I know that I can't hope to preserve the full alpha channel, but surely this function would at least pick up on the transparent background. Is there something I'm missing? Are there any alternative approaches that I can take?

AlexMax
  • 1,204
  • 14
  • 36

3 Answers3

4

I have recently come across something like this - I could only get the transparency working by using:

imagesavealpha($im, true);
imagecolortransparent($im, imagecolorat($im,0,0));

I knew that in all the images, the top left pixel would be the background color. These were called after imagetruecolortopalette and before imagepng.

bjorsq
  • 41
  • 2
  • I tried this, it looked good, but for some reason the PNG on my (WAMP) installation ended up completely garbled then. I'm also trying to convert a true color to a paletted 256 PNG image while preserving the single alpha color. – Philipp Lenssen Apr 30 '12 at 14:06
  • Sorry, it seems that this result only looks garbage when opened in Corel PhotoPaint, Photoshop on the other hand looks fine (including the transparency). – Philipp Lenssen Apr 30 '12 at 14:15
1

I was able to keep trasparency by saving pixels before imagetruecolortopalette with

function check_transparent($im) {
  $width = imagesx($im);
  $height = imagesy($im);
  $pixels = array();
  for($i = 0; $i < $width; $i++) {
      for($j = 0; $j < $height; $j++) {
          $rgba = imagecolorat($im, $i, $j);
          $index = imagecolorsforindex($im, $rgba);
          if($index['alpha'] == 127) {
              $pixels[] = array($i, $j);
          }
      }
  }
  return $pixels;
}

then replacing with

function replacePixels($im,$pixels){
  $color = imagecolorallocatealpha($im, 0, 0, 0, 127);
  foreach($pixels as $pixel)
      imagesetpixel($im, $pixel[0], $pixel[1], $color);
}

as

$tpixels = check_transparent($image);
imagetruecolortopalette($image, true, 255);
replacePixels($image, $tpixels);
Sam
  • 2,950
  • 1
  • 18
  • 26
0

take a look at imagesavealpha in the php-documentation - i think this is what you are looking for.

oezi
  • 51,017
  • 10
  • 98
  • 115
  • Using this function to turn off the alpha channel doesn't properly turn the parts of the picture that were previously transparent into a transparent color. – AlexMax Apr 12 '10 at 14:09