The current implementation of imagecopymerge() produces unexpected results when merging two true colour images especially as imagecopy() produces results more inline with what I would expect.
By way of an example, consider the following code....
<?php
$bg = imagecreatefrompng('tux.png');
$over = imagecreatefrompng('ff-logo-sm.png');
imagealphablending($bg, true);
imagesavealpha($bg, true);
imagecopy($bg, $over, 276, 300, 0, 0, 123, 119);
imagepng($bg, 'tux-fox-imagecopy.png');
?>
Using imagecopy the resulting image is....
As can be seen, the resulting image retains the alpha channel levels of
both source and destination images.
Now with imagecopymerge...
<?php
$bg = imagecreatefrompng('tux.png');
$over = imagecreatefrompng('ff-logo-sm.png');
imagealphablending($bg, true);
imagesavealpha($bg, true);
imagecopymerge($bg, $over, 276, 300, 0, 0, 123, 119, 100);
imagepng($bg, 'tux-fox-imagecopymerge-100-without-patch.png');
?>
The resulting image is...
Destination image retains alpha channel information while the alpha channel
of the source image is ignored.
Applying a 50% reduction in opacity....
<?php
$bg = imagecreatefrompng('tux.png');
$over = imagecreatefrompng('ff-logo-sm.png');
imagealphablending($bg, true);
imagesavealpha($bg, true);
imagecopymerge($bg, $over, 276, 300, 0, 0, 123, 119, 50);
imagepng($bg, 'tux-fox-imagecopymerge-50-without-patch.png');
?>
The resulting image is...
With my patch (applied to ext/gd/libgd/gd.c), the results are more inline with what I would expect imagecopymerge to return ( the patch file can be found here.
<?php
$bg = imagecreatefrompng('tux.png');
$over = imagecreatefrompng('ff-logo-sm.png');
imagealphablending($bg, true);
imagesavealpha($bg, true);
imagecopymerge($bg, $over, 276, 300, 0, 0, 123, 119, 100);
imagepng($bg, 'tux-fox-imagecopymerge-100-with-patch.png');
?>
Gives us....
And with 50% opacity reduction...
<?php
$bg = imagecreatefrompng('tux.png');
$over = imagecreatefrompng('ff-logo-sm.png');
imagealphablending($bg, true);
imagesavealpha($bg, true);
imagecopymerge($bg, $over, 276, 300, 0, 0, 123, 119, 50);
imagepng($bg, 'tux-fox-imagecopymerge-50-with-patch.png');
?>
Gives us....