Craig Marvelley

Software and such

Mounting Alpha Transparent Images With PHP and GD

Yesterday brought a bug in a PHP thumbnail library I’ve been working on: when mounting a 24 bit PNG with alpha transparency onto another ‘framing’ image the transparency was being lost. A simplified version of the code looks something like this:

// Read the transparent image
$image = imagecreatefrompng('transparent.png');
$width = imagesx($image);
$height = imagesy($image);

// Create the mount
$border = 10;
$mountWidth = $width + ($border * 2);
$mountHeight = $height + ($border * 2);
$mount = imagecreatetruecolor($mountWidth, $mountHeight);
$mountColour = imagecolorallocate($mount, 255, 0, 0);
imagefilledrectangle($mount, 0, 0, $mountWidth, $mountHeight, $mountColour);

// Centre the image within the mount
imagecopymerge($mount, $image, $border, $border, 0, 0, $width, $height, 100);

// Output to screen
header('Content-Type: image/png');
imagepng($mount);

This all worked well enough until someone tried mounting a PNG with alpha transparency, whereupon things became very messy. A bit of googling suggested that that the imagecopymerge() function was to blame (I’d used ┬áit because it allowed the manipulation of opacity in the merged image) and that the imagecopy() function handled transparency better – which I found to be the case.

So a transparency-friendly version of the script looks like:

// Read the transparent image
$image = imagecreatefrompng('transparent.png');

...

// Centre the image within the mount
imagecopy($mount, $image, $border, $border, 0, 0, $width, $height);

// Output to screen
header('Content-Type: image/png');
imagepng($mount);

And problem solved – though I’d like to find a way to maintain image transparency while also being able to adjust the opacity of the mounted image.