PHP Merge jpeg on top of png with alpha transparency - php

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

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

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

Related

Remove transparent space from a png image while merging with another png image using PHP GD

I am merging two png images in my php code using php-gd. The images are getting merged, however the problem is that there is extra transparent space in the image which I want to remove.
Here is my php code.
<?php
$image1Url = "/home/sunpure-refined-sunflower-oil-v-5-ltr-1.png";
$image2Url = "/home/hypercity-every-day-sooji-rawa-v-1-kg-6.png";
$dest = imagecreatefrompng($image1Url);
$src = imagecreatefrompng($image2Url);
$offset2x = imagesx($src);
$offset3x = imagesx($dest);
$temp = imagecreatetruecolor($offset2x + $offset3x, 140);
$background = imagecolorallocate($temp, 0, 0, 0);
imagecolortransparent($temp, $background);
imagecopymerge($temp, $src, 0, 0, 0, 0, 180, 180, 100); //have to play with these numbers for it to work for you, etc.
imagecopymerge($temp, $dest, $offset2x-50, 0, 0, 0, 180, 180, 100);
header('Content-Type: image/png');
imagepng($temp, "/home/myImage.png");
imagedestroy($dest);
imagedestroy($src);
In the rightmost image, I was trying to remove the space between them , but due to transparent space, its not happening.

What’s wrong with this PNG Transparent image generator? The background is Black

First: I want to create a PNG image and draw a shape inside it.
Second: Overlap the first PNG on another image (for example a jpg image)
The problem is: When I create the first PNG with a shape inside (the background is not transparent and is dark) so this make a black overlap on second image.
How can I fix it?
I don’t work so much with images function so I got trouble.
Notes: I need to create the first transparent PNG and then overlap it on second image. I don’t want to create shape directly on second image.
And The Code:
<?php
define('EXAMPLE_TMP_SERVERPATH', '');
define('EXAMPLE_TMP_URLRELPATH', '');
$tempDir = EXAMPLE_TMP_SERVERPATH;
$fileName = 'test3img.png';
$imgW = 125;
$imgH = 125;
# First
$base_image = imagecreatetruecolor($imgW, $imgH);
$black = imagecolorallocate($base_image, 0, 0, 0);
imagecolortransparent($base_image, $black);
$col[0] = imagecolortransparent($base_image, $black);
imagealphablending($base_image, true);
imagesavealpha($base_image, true);
imagefill($base_image, 0, 0, $col[0]);
imagefilledrectangle($base_image, 4, 4, 50, 25, 255);
imagepng($base_image, $tempDir.$fileName);
# First2
$target_image = imagecreatetruecolor($imgW*5, $imgH*5);
$black2 = imagecolorallocatealpha($base_image, 0, 0, 0, 127);
imagecolortransparent($target_image, $black2);
imagecopyresized($target_image, $base_image, 0, 0, 0, 0,$imgW, $imgH, $imgW, $imgH);
imagedestroy($base_image);
imagepng($target_image, $tempDir.$fileName);
imagedestroy($target_image);
# First2
# Second
$dest = imagecreatefromjpeg('../avatar.jpg');
$src = imagecreatefrompng(EXAMPLE_TMP_URLRELPATH.$fileName);
imagealphablending($dest, true);
imagesavealpha($dest, true);
imagealphablending($src, true);
imagecopyresampled(
$dest,
$src,
0,0,
0,0,
200, 200,
125, 125
);
imagepng($dest, EXAMPLE_TMP_URLRELPATH.'_m.jpeg');
imagedestroy($dest);
imagedestroy($src);
?>
Need to add the alpha channel too:
Alpha Channel

Image create using gd

I am creating image using GD library all the functions are working fine. But the main problem where i stucked that i want to merge png image over an other image but after overlapping it cannot merge properly and looking like jpg or other instead of png. I cannot upload my image here due to low reputation so click on these links below to see the image.
The image which i want to merge is this
Png image
The image where i merge above image is:
My code is here:
<?php
$im = imagecreate(288,288);
$background_color = imagecolorallocate($im, 230, 248, 248);
$file = 'images/smiley/smile'.$_POST['smiley'].'.png';
$bg = imagecreatefrompng($file);
imagealphablending($im, true);
imagesavealpha($bg, true);
imagecopyresampled($im, $bg, 80, 80, 0, 0, 50, 50, 185, 185);
header("Content-Type: image/png");
$filename = $_SESSION['rand'].'.png';
imagepng($im,$filename);
echo '<img src="'.$filename.'" alt="" />';
?>
Your background image doesn't have an alpha channel. This makes the PHP GD library do all of it's copying operations without using an alpha channel, instead just setting each pixel to be fully opaque or transparent, which is not what you want.
The simplest solution to this is to create a new image of the same size as the background that has an alpha channel, and then copy both the background and face into that one.
$baseImage = imagecreatefrompng("../../var/tmp/background.png");
$topImage = imagecreatefrompng("../../var/tmp/face.png");
// Get image dimensions
$baseWidth = imagesx($baseImage);
$baseHeight = imagesy($baseImage);
$topWidth = imagesx($topImage);
$topHeight = imagesy($topImage);
//Create a new image
$imageOut = imagecreatetruecolor($baseWidth, $baseHeight);
//Make the new image definitely have an alpha channel
$backgroundColor = imagecolorallocatealpha($imageOut, 0, 0, 0, 127);
imagefill($imageOut, 0, 0, $backgroundColor);
imagecopy($imageOut, $baseImage, 0, 0, 0, 0, $baseWidth, $baseHeight); //have to play with these
imagecopy($imageOut, $topImage, 0, 0, 0, 0, $topWidth, $topHeight); //have to play with these
//header('Content-Type: image/png');
imagePng($imageOut, "../../var/tmp/output.png");
That code produces this image:

Image transparency not preserved when merging two images in PHP

When using examples from other posts to try and merge one PNG that has transparent parts on it with another non-transparent PNG, the foreground PNGs transparency is lost and defaults to white.
The code so far:
$width = 349;
$height = 250;
$base_image = imagecreatefrompng($_GET['bg']);
$top_image = imagecreatefrompng($_GET['fg']);
$merged_image = "merged.png";
imagesavealpha($top_image, true);
imagealphablending($top_image, true);
imagecopy($base_image, $top_image, 0, 0, 0, 0, $width, $height);
imagepng($base_image, $merged_image);
Can anyone suggest where I may be going wrong?
Coming out like this
Should look like this
Copy from Can PNG image transparency be preserved when using PHP's GDlib imagecopyresampled?
Codes should be like this:
imagesavealpha($base_image, true);
imagealphablending($base_image, false);
$image = imagecreatefrompng($_GET['bg']);
$frame = imagecreatefrompng($_GET['fg']);
imagealphablending($frame,true);
imagecopymerge($image, $frame, 0, 0, 0, 0, 0, 100, 100);
# Save the image to a file
imagepng($image, 'file-xyz.png');

Background transperancy in imagerotate()

Since last 2 days, I was trying to add transperancy to the background after rotating an image using imagerotate() PHP-GD function.
But, to my great disappointment, it's not working at all.
It's just giving out a black background behind it.
Here's my code -
$patchImageS = 'image.png'; // the image to be patched over the final bg
$patchImage = imagecreatefrompng($patchImageS); // resource of image to be patched
$patchImage = imagerotate($patchImage, 23, 0, 0);
imagepng($patchImage,'tt.png');
I tried to change the parameters being passed in function to
imagerotate($patchImage, 23, 5, 0);
imagerotate($patchImage, 23, 0, 5);
Any help would be highly appreciated.
After a number of 99% finished answers, here's the solution I've found:
// Create, or create from image, a PNG canvas
$png = imagecreatetruecolor($width, $height);
// Preserve transparency
imagesavealpha($png , true);
$pngTransparency = imagecolorallocatealpha($png , 0, 0, 0, 127);
imagefill($png , 0, 0, $pngTransparency);
// Rotate the canvas including the required transparent "color"
$png = imagerotate($png, $rotationAmount, $pngTransparency);
// Set your appropriate header
header('Content-Type: image/png');
// Render canvas to the browser
imagepng($png);
// Clean up
imagedestroy($png);
The key here is to include your imagecolorallocatealpha() in your imagerotate() call...
look for imagesavealpha() in the php-documentation - i think this is what you are looking for.
EDIT: here's an example:
$png = imagecreatefrompng('./alphachannel_example.png');
// Do required operations
$png = imagerotate($png, 23, 0, 0);
// Turn off alpha blending and set alpha flag
imagealphablending($png, false);
imagesavealpha($png, true);
// Output image to browser
header('Content-Type: image/png');
imagepng($png);
imagedestroy($png);
For anyone having problems with imagecopyresampled or imagerotate with black bars on background, I have found a code example here:
https://qna.habr.com/q/646622#answer_1417035
// get image sizes (X,Y)
$wx = imagesx($imageW);
$wy = imagesy($imageW);
// create a new image from the sizes on transparent canvas
$new = imagecreatetruecolor($wx, $wy);
$transparent = imagecolorallocatealpha($new, 0, 0, 0, 127);
$rotate = imagerotate($imageW, 280, $transparent);
imagealphablending($rotate, true);
imagesavealpha($rotate, true);
// get the newest image X and Y
$ix = imagesx($rotate);
$iy = imagesy($rotate);
//copy the image to the canvas
imagecopyresampled($destImg, $rotate, 940, 2050, 0, 0, $ix, $iy, $ix, $iy);

Categories