phppnggd2

PHP Merge jpeg on top of png with alpha transparency


I am trying to put a jpeg behind a png - where the png has alpha transparency.

The foreground image is here: http://peugeot208.srv.good-morning.no/images/marker-shadow.png

The image behind is a facebook profile image - typically like this: https://graph.facebook.com/100000515495823/picture

The result image looses transparency and is black instead: http://peugeot208.srv.good-morning.no/libraries/cache/test.png

This is the code I use:

// combine image with shadow
$newCanvas = imagecreatetruecolor(90,135);
$shadow = imagecreatefrompng("marker-shadow.png");  

//imagealphablending($newCanvas, false);
imagesavealpha($newCanvas, true);   

imagecopy($newCanvas, $canvas, 20, 23, 0, 0, 50, 50);
imagecopy($newCanvas, $shadow, 0, 0, 0, 0, 90, 135);
imagepng($newCanvas, $tempfile, floor($quality * 0.09));

If I enable imagealphablending($newCanvas, false);, the result is correct (with the hole in the middle of the marker being transparent) BUT the image behind is gone.

Can you shed light on this? :-)

Thanks!

Edit: Found a solution

I did some fiddling and ended up with this code - where the origin is not a createimagetruecolor but an image created from a template - which is a transparent png.

Now it works - the result is properly transparent. I don't really know why. Got an idea why?

fbimage.php

// Create markerIcon 
$src = $_REQUEST['fbid'];

$base_image = imagecreatefrompng("../images/marker-template.png");
$photo = imagecreatefromjpeg("https://graph.facebook.com/".$src."/picture");
$top_image = imagecreatefrompng("../images/marker-shadow.png");

imagesavealpha($base_image, true);
imagealphablending($base_image, true);

imagecopy($base_image, $photo, 20, 23, 0, 0, 50, 50);
imagecopy($base_image, $top_image, 0, 0, 0, 0, 90, 135);
imagepng($base_image, "./cache/".$src.".png");

?>

<img src="./cache/<?php echo $src ?>.png" />

Update: Check the following code You can find the result here: http://peugeot208.srv.good-morning.no/images/marker.php As you can see, the background is still black.

// create base image
$base_image = imagecreatetruecolor(90,135);
$photo = imagecreatefromjpeg("marker-original.jpg");
$top_image = imagecreatefrompng("marker-shadow.png");

imagesavealpha($top_image, true);
imagealphablending($top_image, true);

imagesavealpha($base_image, true);
imagealphablending($base_image, true);

// merge images
imagecopy($base_image, $photo, 20, 23, 0, 0, 50, 50);
imagecopy($base_image, $top_image, 0, 0, 0, 0, 90, 135);

// return file
header('Content-Type: image/png');
imagepng($base_image);

Solution

  • The solution was to allocate a color as 100 % alpha transparent and then draw a square on the entire canvas of the base image:

    // create base image
    $base_image = imagecreatetruecolor(90,135);
    
    // make $base_image transparent
    imagealphablending($base_image, false);
    $col=imagecolorallocatealpha($base_image,255,255,255,127);
    imagefilledrectangle($base_image,0,0,90,135,$col);
    imagealphablending($base_image,true);    
    imagesavealpha($base_image, true);
    // --- 
    
    $photo = imagecreatefromjpeg("marker-original.jpg");
    $top_image = imagecreatefrompng("marker-shadow.png");
    
    // merge images
    imagecopy($base_image, $photo, 20, 23, 0, 0, 50, 50);
    imagecopy($base_image, $top_image, 0, 0, 0, 0, 90, 135);
    
    // return file
    header('Content-Type: image/png');
    imagepng($base_image);