PHP Merge jpeg over png with alpha transparency
I'm trying to put jpeg behind png - where png has alpha transparency.
Foreground image: http://peugeot208.srv.good-morning.no/images/marker-shadow.png
The picture on the back is a facebook profile picture - it usually looks like this: https://graph.facebook.com/100000515495823/picture
The resulting image loses transparency and is black instead: http://peugeot208.srv.good-morning.no/libraries/cache/test.png
This is the code I'm using:
// 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 enablealphablending ($ newCanvas, false) is enabled, the result is correct (with a hole in the middle of the transparent marker), but the image behind is gone.
Can you shed some light on this? :-)
Thank!
Edit: found a solution
I played around a bit and ended up with this code where the origin is not createimagetruecolor, but an image created from a template that is a transparent png.
Now it works - the result will be transparent. I really don't know why. Any 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 The result can be found 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);
The solution was to highlight the color as 100% alpha transparent and then draw a square over 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);
Run the following php script and see what weather https are available for this set of arrays.
echo "<pre>"; print_r (stream_get_wrappers ()); echo "</pre>";
out put will be like this.
Array ( [0] => php [1] => file [2] => glob [3] => data [4] => http [5] => ftp [6] => zip [7] => compress.zlib [8] => https [9] => ftps [10] => compress.bzip2 [11] => phar )
here array element 8th shows that https is enabled. If this is not available in your code then. Find the php.ini file and put the following line there.
extension = php_openssl.dll
After that, restart the servers, then your function will work even with facebook resource url.
I am trying the following code, it works well for me.
$ width = 400; $ height = 400; $ base_image = imagecreatefromjpeg ("base.jpg"); $ top_image = imagecreatefrompng ("top.png"); imagesavealpha ($ top_image, false); imagealphablending ($ top_image, false); imagecopy ($ base_image, $ top_image, 0, 0, 0, 0, $ width, $ height); imagepng ($ base_image, "merged.png");
I check the first script. For all transparent pngs, you must apply the following code.
imagesavealpha ($ shadow, true); imagealphablending ($ shadow, true);
the other is reasonable that there will be filled with black. You haven't applied it here for the "marker-shadow.png" file object
Been struggling with this for some time now and none of the answers here helped me completely. Below is the code that worked fine when trying to click a JPG over a transparent PNG (note the "// !!! *" comments, they are important):
// create a true colour, transparent image
// turn blending OFF and draw a background rectangle in our transparent colour
$image=imagecreatetruecolor($iwidth,$iheight);
imagealphablending($image,false);
$col=imagecolorallocatealpha($image,255,255,255,127);
imagefilledrectangle($image,0,0,$iwidth,$iheight,$col);
imagealphablending($image,true);
// ^^ Alpha blanding is back on.
// !!! *** IMAGE MANIPULATION STUFF BELOW ***
$backImage = imagecreatefrompng("yourimage.png");
imagecopyresampled($image, $backImage, 0, 0, 0, 0, 400, 300, 400, 300);
$foreImage = imagecreatefromjpeg("yourimage.png");
imagecopyresampled($image, $foreImage, 10, 10, 0, 0, 200, 150, 200, 150);
// !!! *** IMAGE MANIPULATION STUFF ABOVE ***
// output the results...
header("Content-Type: image/png;");
imagealphablending($image,false);
imagesavealpha($image,true);
imagepng($image);
Credits: http://www.bl0g.co.uk/creating-transparent-png-images-in-gd.html
// create base image
$photo = imagecreatefromjpeg("Penguins.jpg");
$frame = imagecreatefrompng("frame.png");
// get frame dimentions
$frame_width = imagesx($frame);
$frame_height = imagesy($frame);
// get photo dimentions
$photo_width = imagesx($photo);
$photo_height = imagesy($photo);
// creating canvas of the same dimentions as of frame
$canvas = imagecreatetruecolor($frame_width,$frame_height);
// make $canvas transparent
imagealphablending($canvas, false);
$col=imagecolorallocatealpha($canvas,255,255,255,127);
imagefilledrectangle($canvas,0,0,$frame_width,$frame_height,$col);
imagealphablending($canvas,true);
imagesavealpha($canvas, true);
// merge photo with frame and paste on canvas
imagecopyresized($canvas, $photo, 0, 0, 0, 0, $frame_width, $frame_height,$photo_width, $photo_height); // resize photo to fit in frame
imagecopy($canvas, $frame, 0, 0, 0, 0, $frame_width, $frame_height);
// return file
header('Content-Type: image/png');
imagepng($canvas);
// destroy images to free alocated memory
imagedestroy($photo);
imagedestroy($frame);
imagedestroy($canvas);