There may be a cleaner way to do this, but it seems to work. However, the image files for the add-on pieces seemed to not quite match the horse image, and I had to shift them left and down a bit to match. I found I had to use imagecreattruecolor() to avoid some of the problems you described, along with imagecopyresampled(). (You're also lucky that I'm suffering from severe insomnia tonight. 😉 )
<?php
/**
* Build a horse
* @return resource GD image
* @param string $base File path
* @param array $addOns Files to add to the base image
*/
function makeHorse($base, $addOns=array())
{
if(!file_exists($base)) {
user_error("Cannot find '$base'");
return false;
}
if(!is_array($addOns)) {
user_error("2nd arg must be array");
return false;
}
else {
foreach($addOns as $file) {
if(!file_exists($file)) {
user_error("Cannot find '$file'");
return false;
}
}
}
$baseImg = imagecreatefrompng($base);
if($baseImg == false) {
user_error("Could not create base PNG image from '$base'");
return false;
}
$w = imagesx($baseImg);
$h = imagesy($baseImg);
$img = imagecreatetruecolor($w, $h);
$bgcolor = imagecolorallocatealpha($img, 255, 255, 255, 0);
imagefilledrectangle($img, 0, 0, $w - 1, $h - 1, $bgcolor);
imagecopyresampled($img, $baseImg, 0, 0, 0, 0, $w, $h, $w, $h);
imagedestroy($baseImg);
foreach($addOns as $file) {
$layer = imagecreatefrompng($file);
if($layer == false) {
user_error("Could not create layer PNG from '$file'");
imagedestroy($img);
return false;
}
// This is where I had to tweak the offset of the add-on pieces (the -23, 9):
imagecopyresampled($img, $layer, -23, 9, 0, 0, $w, $h, $w, $h);
}
return $img;
}
// Let's build a horse
$image = makeHorse('black.png', array('front-socks.png', 'strip.png'));
if($image == false) {
die("Oops!");
}
header("Content-Type: image/png");
imagepng($image);