Deutsch English
Programming Diesen Artikel auf Deutsch lesen

Preserve PNG transparency with GD Lib

Semi-transparent PNG

Lately I had to write a PHP function that generates differently sized thumbnails from an image with GD Lib. Thereby I had lots of trouble with semi-transparent PNG graphics. Although I found many tips on the internet that pointed me in the right direction, I couldn’t find a really complete and neat solution. Many people emphasized the oh so big importance of the functions imagealphablending() and imagesavealpha(), which – as it later transpired – were completely meaningless for my purposes.
Well, I’ll write the solution down here as usual, in case somebody else is looking for it as desperately as I did – or in case I forget it. ;) The pretty red dot here on the right will serve as visualization.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
$filename = "rotverlauf.png";
 
$oldimg = imagecreatefrompng($filename);
 
$oldwidth = imagesx($oldimg);
$oldheight = imagesy($oldimg);
$newwidth = $oldwidth/2;
$newheight = $oldheight/2;
 
$newimage = imagecreate($newwidth, $newheight);
$color = imagecolorallocatealpha($newimage, 0, 0, 0, 127);
imagefill($newimage, 0, 0, $color);
 
imagecopyresampled($newimage, $oldimg, 0, 0, 0, 0, $newwidth, $newheight, $oldwidth, $oldheight);

The trick is to first create a new image ($newimage) and fill it with a transparent background color ($color). If you now copy the original image into it with the help of imagecopyresampled(), the transparency will be preserved.
The example script reduces the red dot to half its size. The result can be seen on the left.

But I had yet another problem: I wanted to save the thumbnails of PNG graphics in the JPEG format, too, i. e. put them on a white or black background, while the color gradient should of course be preserved. After a few unsuccessful attempts, the solution turned out to be quite simple. ;) You just have to replace the functions imagecreate() by imagecreatetruecolor() and imagecolorallocatealpha() by imagecolorallocate(). Ergo:

10
11
$newimage = imagecreatetruecolor($newwidth, $newheight);
$color = imagecolorallocate($newimage, 255, 255, 255);

As you can see, I chose white (255, 255, 255) as background color this time, because it looks better than black in most of the cases.
Actually I could have used imagecreatetruecolor() in the first example, too, when creating a PNG. But some servers (like mine) seem to have problems with that, so you should rather stick with imagecreate() when making PNGs.
On the right you can now see the fantastic red dot as JPEG.

Now that the new image is ready, you can either save it to a file:

imagepng($nm, "neuer-dateiname.png"); //bzw. imagejpeg();

or output it directly:

header("Content-type: image/png"); //bzw. image/jpg
imagepng($nm); //bzw. imagejpeg();

Update (12th October 2009)

It has been brought to my attention that my version doesn’t seem to work correctly on every server either. If that is the case, you can try to replace the lines 11 and 12 by the following:

11
12
13
$color = imagecolorallocate($nm, 255, 255, 255);
imagefill($nm, 0, 0, $color);
imagecolortransparent($nm, $color);


Comments

  1. 18th August 2016
    12:47 am

    Detlev flag

    Danke für diesen Post und das Update vom 12.10.2009 … es hat mein Problem gelöst !

  2. 21st October 2015
    7:40 pm

    Joe flag

    This solution is still valid today, 2015. The only other solution is to change the image library itself to Imagmagick.

  3. 17th October 2012
    1:42 pm

    Sergey flag

    Thanks a lot for this post!

  4. 30th October 2010
    10:45 pm

    Fred flag

    Merci beaucoup pour ce bout de code, ca faisait des heures que je cherchais… Tu as sauvé ma nuit de sommeil !

    Thanks you very much for this piece of source code, i’ve searched for a solution about hours and hours… You saved my sleeping night !

  5. 21st May 2010
    11:01 am

    Piotr flag

    thank you a lot for your discovery, I have searched for it for a long time,
    the key is to use imagecreate() instead of imagecreatetruecolor() for transparent png files

Write comment

Allowed HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <p> <pre lang="" line="" escaped=""> <q cite=""> <strike> <strong> <img src="" alt="" class="" width="" height=""> | Code snippets can be posted in `backticks`. Example: `<?php echo "Hi!"; ?>`