views:

1153

answers:

2

I'm using GD to resize and convert images, however during my tests I found a weird behavior when converting transparent PNG's to JPEG's. According to the manual ImageAlphaBlending() is on by default but in order to preserve the transparency I must set ImageSaveAlpha() to true (which in turn requires that I set ImageAlphaBlending() to false). So the correct way should be:

$result = ImageCreateFromPNG(...);
ImageAlphaBlending($result, false);
ImageSaveAlpha($result, true);
ImageFill($result, 0, 0, IMG_COLOR_TRANSPARENT);
ImageJPEG($result);
ImageDestroy($result);

However if I do it the "correct" way all the transparency area comes up black in the JPEG. This seems to work (JPEG with white background on transparent areas) on my tests:

$result = ImageCreateFromPNG(...);
ImageAlphaBlending($result, true); // true by default, but still...
ImageSaveAlpha($result, true);
ImageFill($result, 0, 0, IMG_COLOR_TRANSPARENT);
ImageJPEG($result);
ImageDestroy($result);

Can someone please enlighten me on this subject?

+3  A: 

It probably depends on your PNG. A PNG file can contain a background color, which can be used when transparency doesn't work. Your PNG probably has a white background. When you set imageaplhablending to true it picks up the background color from your PNG and uses that when writing the JPEG. When you set it to false it picks the default for GD which is black.

You can try it for yourself. Create a transparent PNG and save it with an orange or pink background color. Your second example should show that color.

By the way, the PNG background color trick is a nice one for IE6 images. IE6 does not support transparent PNGs so it will display them with whatever background color you saved them with. When saving transparent PNGs, save them with the same background color as your website. It will look better than white or black boxes around your PNG images in IE6.

Sander Marechal
+2  A: 

If you are converting from PNG (or GIF) to JPG, you should probably copy the final image to another image that is filled with white, using imagecopy ($image is any image already created with GD):

// Create a new background
$bg = imagecreatetruecolor(imagesx($image), imagesy($image));

// Allocate the color
$color = imagecolorallocate($bg, 255, 255, 255);

// Fill the background with white
imagefill($bg, 0, 0, $color);

// Alpha blending must be enabled on the background!
imagealphablending($bg, TRUE);

// Copy the current image onto the opaque background
if (imagecopy($bg, $image, 0, 0, 0, 0, imagesx($image), imagesy($image)))
{
    // Replace the image with the background copy
    imagedestroy($image);
    $image = $bg;
}

Hope that helps.

shadowhand
Commenting the imagealphablending($bg, TRUE); line gives me the exactly same result, nonetheless that is pretty much what I'm doing with the IMG_COLOR_TRANSPARENT constant. My main doubt here is the simultaneous use of ImageAlphaBlending and ImageSaveAlpha, both set to true. That's the only way I get correct results but the manual says it's wrong and that both cannot be true at the same time.
Alix Axel
Not sure what your code is doing then, but the above code worked for me.
shadowhand