Question

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);
Was it helpful?

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

OTHER TIPS

Run following php script and see weather https available on that array set.

    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 https is enabled. If that not available on your code then. Find php.ini file and place following line there.

extension=php_openssl.dll

After that restart servers then your function will work with facebook resource url even.

I try 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 png you have to apply following code.

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

other wise that black coloured filling will be there. Here you didn't apply that for "marker-shadow.png" file object

Struggled with this for a while and none of the answers here helped me fully. Below is the code that worked perfectly when trying to slap JPG on top of transparent PNG (pay attention to 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);
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top