Reputation: 351
I have a custom bicycle configurator that layers transparent png files with css. http://www.gallantbicycles.com/build/no1/
I need to add the ability to combine them into one file dynamically so the user can download an image or share it.
This is where I'm at right now, but it results in a black background and only the front most image is seen in the result:
$width = 720;
$height = 500;
$layers = array();
$layers[] = imagecreatefrompng("pathtomyimage/image.png");
$layers[] = imagecreatefrompng("pathtomyimage/image.png");
$layers[] = imagecreatefrompng("pathtomyimage/image.png");
$image = imagecreatetruecolor($width, $height);
imagealphablending($image, false);
imagesavealpha($image, true);
for ($i = 0; $i < count($layers); $i++) {
imagecopymerge($image, $layers[$i], 0, 0, 0, 0, $width, $height, 100);
}
header('Content-type: image/png');
imagepng($image);
Upvotes: 1
Views: 5678
Reputation: 4436
All right! I combined all of your answers to come up with a solution that actually works!
Thanks for the help and I hope this helps someone!
$width = $height = null;
$layers = [];
foreach ($imageLayerPaths as $layer) {
if (!is_file($layer)) {
continue;
}
$layers[] = imagecreatefrompng($layer);
if ($width === null) {
$size = getimagesize($layer);
$width = $size[0];
$height = $size[1];
}
}
if (empty($layers)) {
throw new \Exception("No valid image layers to create the image");
}
// Create image base with transparent background
$image = imagecreatetruecolor($width, $height);
imagealphablending($image, false);
$transparency = imagecolorallocatealpha($image, 0, 0, 0, 127);
imagefill($image, 0, 0, $transparency);
imagesavealpha($image, true);
// Add each layer on the image
imagealphablending($image, true);
foreach ($layers as $layer) {
imagecopyresampled($image, $layer, 0, 0, 0, 0, $width, $height, $width, $height);
}
imagealphablending($image, false);
imagesavealpha($image, true);
imagepng($image, "path/where/you/want/to/save/the/image.png");
Upvotes: 0
Reputation: 1383
Here is code which works:
$width = 210;
$height = 190;
$layers = array();
$layers[] = imagecreatefrompng("img/01_boy_faceB.png");
$layers[] = imagecreatefrompng("img/01_boy_hairB.png");
$image = imagecreatetruecolor($width, $height);
// to make background transparent
imagealphablending($image, false);
$transparency = imagecolorallocatealpha($image, 0, 0, 0, 127);
imagefill($image, 0, 0, $transparency);
imagesavealpha($image, true);
/* if you want to set background color
$white = imagecolorallocate($image, 255, 255, 255);
imagefill($image, 0, 0, $white);
*/
imagealphablending($image, true);
for ($i = 0; $i < count($layers); $i++) {
imagecopy($image, $layers[$i], 0, 0, 0, 0, $width, $height);
}
imagealphablending($image, false);
imagesavealpha($image, true);
imagepng($image, 'final_img.png');
?>
Upvotes: 0
Reputation: 239
Try this solution: Merge two images with transparencies in PHP
use imagecopyresampled instead of imagecopymerge
Upvotes: 1
Reputation: 19895
You have to replace this code
imagealphablending($image, false);
imagesavealpha($image, true);
for ($i = 0; $i < count($layers); $i++) {
imagecopymerge($image, $layers[$i], 0, 0, 0, 0, $width, $height, 100);
}
by
imagealphablending($image, true);
for ($i = 0; $i < count($layers); $i++) {
imagecopymerge($image, $layers[$i], 0, 0, 0, 0, $width, $height, 100);
}
imagealphablending($image, false);
imagesavealpha($image, true);
imagealphablending
must be true
in order to correcly stack the layers, but it must be false
to save the image.
Upvotes: 1