1

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);
Jason Wood
  • 351
  • 1
  • 5
  • 13
  • 1
    possible duplicate of [Can PNG image transparency be preserved when using PHP's GDlib imagecopyresampled?](http://stackoverflow.com/questions/32243/can-png-image-transparency-be-preserved-when-using-phps-gdlib-imagecopyresample) – Orangepill Aug 16 '13 at 20:50
  • I've already tried adding the lines "imagealphablending($image, false);" and "imagesavealpha($image, true);" so I think my problem is different. Additionally, I'm not resizing one image, but trying to layer multiple. – Jason Wood Aug 17 '13 at 16:33
  • Use this proven functional procedure: http://stackoverflow.com/a/23078863/1277159 – WSD Apr 15 '14 at 12:50

4 Answers4

1

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.

Lorenz Meyer
  • 19,166
  • 22
  • 75
  • 121
1

Try this solution: Merge two images with transparencies in PHP

use imagecopyresampled instead of imagecopymerge

Community
  • 1
  • 1
PepeNietnagel
  • 230
  • 2
  • 10
0

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');

?>
atulmy
  • 1,364
  • 15
  • 23
0

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");
Chris
  • 4,277
  • 7
  • 40
  • 55