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);
source to share
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);
source to share
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.
source to share
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
source to share
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
source to share
// 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);
source to share