Image with transparanent background becoming white when added with imagecopymerge - php

I'm using imagecopymerge to place an image on top of another image, however, when I do so, the transparent part of the image becomes white, which isn't what I am after. So the images I have are the below as the background:
And the image I am adding on top of it, with transparent background, is this:
This, however, (along with the rest of my code) results in the area around the circle, and within the boundaries being white:
The code I am using at the moment to inject the value is:
$magical = imagecreatefrompng('Magical.png');
imagecopymerge($img, $magical, 366, 135, 0, 0, 32, 32, 100);
Research has said I should try using things like imagealphablending or imagecopy instead of imagecopymerge, but that didn't work. I've also found references to trying imagecolortransparent and imagecolorallocate but that didn't work either. So, for example, neither of these attempts worked:
$magical = imagecreatefrompng('Magical.png');
$white = imagecolorallocate($output, 255, 255, 255);
imagecolortransparent($magical, $white);
imagecopymerge($img, $magical, 366, 135, 0, 0, 32, 32, 100);
// or this attempt
$magical = imagecreatefrompng('Magical.png');
imagealphablending($img, true);
imagealphablending($magical, true);
imagecopymerge($img, $magical, 366, 135, 0, 0, 32, 32, 100);
What am I missing here? How do I ensure that when the image is added to the other its transparency is retained?

I pulled your images into my local machine and used the imagecopymerge_alpha function listed on the PHP Documentation - https://www.php.net/manual/en/function.imagecopymerge.php#92787
<?php
function imagecopymerge_alpha($dst_im, $src_im, $dst_x, $dst_y, $src_x, $src_y, $src_w, $src_h, $pct){
// creating a cut resource
$cut = imagecreatetruecolor($src_w, $src_h);
// copying relevant section from background to the cut resource
imagecopy($cut, $dst_im, 0, 0, $dst_x, $dst_y, $src_w, $src_h);
// copying relevant section from watermark to the cut resource
imagecopy($cut, $src_im, 0, 0, $src_x, $src_y, $src_w, $src_h);
// insert cut resource to destination image
imagecopymerge($dst_im, $cut, $dst_x, $dst_y, 0, 0, $src_w, $src_h, $pct);
}
$img = imagecreatefrompng('baseImage.png');
$magical = imagecreatefrompng('overlay.png');
imagecopymerge_alpha($img, $magical, 366, 135, 0, 0, 32, 32, 100);
imagepng($img, "./test.png");

Related

Merge an image with background image gives black background in php

I have a light blue image set as $dest.
I have the logo set as logo1
I want to insert the logo into the light blue image. So I tried the following:
<?php
$dest = imagecreatefrompng('template.png');
$logo1 = 'tst.png';
$logo1created = imagecreatefrompng($logo1);
imagealphablending($logo1created,true);
imagesavealpha($logo1created, true);
$logo1width = imagesx($logo1created);
$logo1height = imagesy($logo1created);
$bg_color = imagecolorat($logo1created,1,1); //get color of top-left pixel
imagecolortransparent($logo1created, $bg_color);
imagecopymerge($dest, $logo1created, 70, 132, 0, 0, $logo1width, $logo1height, 100);
header('Content-Type: image/png');
imagepng($dest);
imagedestroy($dest);
imagedestroy($logo1created);
?>
I get the following as the output.
The logo is not transparent (it has a white background) and I have resized the image to 124*30
I want to set transparent background to the logo when I do that there is a black background as per the screenshot above. I am not sure why? Also, the image is blurred. Can someone help me fix this?
Thanks!
Please try the following: (you may adjust the x and y by changing the values 60,70 to other values)
<?php
function imagecopymerge_alpha($dst_im, $src_im, $dst_x, $dst_y, $src_x, $src_y, $src_w, $src_h, $pct){
// creating a cut resource
$cut = imagecreatetruecolor($src_w, $src_h);
// copying relevant section from background to the cut resource
imagecopy($cut, $dst_im, 0, 0, $dst_x, $dst_y, $src_w, $src_h);
// copying relevant section from watermark to the cut resource
imagecopy($cut, $src_im, 0, 0, $src_x, $src_y, $src_w, $src_h);
// insert cut resource to destination image
imagecopymerge($dst_im, $cut, $dst_x, $dst_y, 0, 0, $src_w, $src_h, $pct);
}
$base = imagecreatefrompng('template.png');
$logo1 = 'tst.png';
$logo = imagecreatefrompng($logo1);
imagecopymerge_alpha($base, $logo, 60, 70, 0, 0, 124, 30, 100);
header('Content-Type: image/png');
imagepng($base);
?>

merging two png images in php

I am trying to merge my two images in php. One image is being uploaded frim my system and the other is the one I am creating with transparent background.
Here is my code. My code is just showing a non-image icon.
I don't understand where I am wrong.
<?php
//Set the Content Type
header("Content-type: image/png");
#dispaly the image
$file=$_GET['file'];
// echo file_get_contents($file);
$im = imagecreatetruecolor(250, 200);
$black = imagecolorallocate($im, 255, 255, 255);
$blue = imagecolorallocate($im, 0, 0, 255);
imagecolortransparent($im, $black);
//text to draw
$text="hello world";
//font path
$font = '/usr/share/fonts/truetype/droid/DroidSans.ttf';
// Add the text
imagettftext($im, 15, 0, 50, 50, $blue, $font, $text);
$dest=imagecreatefrompng($file);
$src=imagecreatefrompng($im);
imagealphablending($dest, false);
imagesavealpha($dest, true);
imagecopymerge($dest, $src, 10, 10, 0, 0, 100, 250, 200);
imagepng($dest);
imagedestroy($dest);
imagedestroy($src);
?>
Use $im not $src - as Sayed pointed out, imagecreatefrompng takes filename (string) as argument - not GD resource. Why set $src if $im already contains GD resource ready for use?
There is important part with imagettftext. I was able to reproduce the effect of empty icon if GD cannot find a font in given path. Check your location, permissions and letter case. Also, if you decide to just copy the .ttf file right into script location, refer to imagettftext() documentation as there is important caveat with ".ttf" extension.
Also, to create fully transparent image use:
(by George Edison in PHP doc for imagefill
$im = imagecreatetruecolor(317, 196);
$transparent = imagecolorallocatealpha($im, 0, 0, 0, 127);
imagefill($im, 0, 0, $transparent);
imagesavealpha($im, TRUE);
Also, from PHP doc for imagecopymerge() by Sina Salek: imagecopymerge_alpha function to provide for true transperency in imagecopymerge()
So, my solution:
<?php
//Set the Content Type
header("Content-type: image/png");
#dispaly the image
$file='test.png';
$im = imagecreatetruecolor(317, 196);
$transparent = imagecolorallocatealpha($im, 0, 0, 0, 127);
imagefill($im, 0, 0, $transparent);
imagesavealpha($im, TRUE);
$blue = imagecolorallocatealpha($im, 0, 0, 255, 0);
//text to draw
$text="hello world";
putenv('GDFONTPATH=' . realpath('.'));
$font = 'lucida';
imagettftext($im, 20, 0, 10, 50, $blue, $font, $text);
$dest=imagecreatefrompng($file);
imagealphablending($dest, false);
imagesavealpha($dest, true);
imagecopymerge_alpha($dest, $im, 10, 10, 0, 0, 200, 180, 100);
imagepng($dest);
imagedestroy($dest);
imagedestroy($im);
function imagecopymerge_alpha($dst_im, $src_im, $dst_x, $dst_y, $src_x, $src_y, $src_w, $src_h, $pct){
// creating a cut resource
$cut = imagecreatetruecolor($src_w, $src_h);
// copying relevant section from background to the cut resource
imagecopy($cut, $dst_im, 0, 0, $dst_x, $dst_y, $src_w, $src_h);
// copying relevant section from watermark to the cut resource
imagecopy($cut, $src_im, 0, 0, $src_x, $src_y, $src_w, $src_h);
// insert cut resource to destination image
imagecopymerge($dst_im, $cut, $dst_x, $dst_y, 0, 0, $src_w, $src_h, $pct);
}
?>
You should use imagecopymerge() function for this.
Find out link
http://php.net/manual/en/function.imagecopymerge.php

Combining transparent pngs

I have looked here on SO for solutions for my problem, but I can't find a solution that seems to work for me. Maybe I'm doing something wrong.
I am merging a number of transparent PNGs together, into one display for the customer. There are pretty much three layers (obviously the background is transparent, then fairly rectangular PNGs, but somewhat out of square, and then smaller ones on top of that).
The top layer of smaller images goes on the rectangles nicely. But the rectangles look as though they were filled with black first, then the image applied - you can see this because the image is slightly out of square, so the edges usually have this black line around it. The thing that I don't understand is why this layer has it and not the top - both images are instantiated with the same code.
Here is my code (I found the imagecopymerge_alpha function somewhere, and it seems to do pretty well, but obviously, not entirely).
// Merging:
$this->imagecopymerge_alpha($this->image, $resizedImage, $startX, $startY, 0, 0, imagesx($resizedImage), imagesy($resizedImage), 100);
function imagecopymerge_alpha($dst_im, $src_im, $dst_x, $dst_y, $src_x, $src_y, $src_w, $src_h, $pct){
// creating a cut resource
$cut = imagecreatetruecolor($src_w, $src_h);
// copying relevant section from background to the cut resource
imagecopy($cut, $dst_im, 0, 0, $dst_x, $dst_y, $src_w, $src_h);
// copying relevant section from watermark to the cut resource
imagecopy($cut, $src_im, 0, 0, $src_x, $src_y, $src_w, $src_h);
// insert cut resource to destination image
imagecopymerge($dst_im, $cut, $dst_x, $dst_y, 0, 0, $src_w, $src_h, $pct);
}
// Creating the background/container image:
private function createTransparent($width, $height)
{
$image = imagecreatetruecolor($width, $height);
imagealphablending($image, false);
imagesavealpha($image, true);
$transparentColor = imagecolorallocatealpha($image, 255, 255, 255, 127);
imagefill($image, 0, 0, $transparentColor);
return $image;
}
So, my question is this: do you see anything in here that would make a transparent PNG not maintain it's transparency and merge correctly with a base transparent PNG?

Adding some opacity on an image with imagecopymerge in PHP

Here my problem:
I want to change the opacity of an image, by copying it on another transparent image.
My code:
$opacity = 50;
$transparentImage = imagecreatetruecolor($width, $height);
imagesavealpha($transparentImage, true);
$transColour = imagecolorallocatealpha($transparentImage , 0, 0, 0, 127);
imagefill($transparentImage , 0, 0, $transColour);
imagecopymerge($transparentImage, $image, 0, 0, 0, 0, $width, $height, $opacity);
$image = $transparentImage;
header('Content-type: image/png');
imagepng($image);
By doing this, when I use imagecopymerge, $transparentImage loses its transparency... So $image is merged on a black image... and not on a transparent image !
However, when I show $transparentImage before calling imagecopymerge, the image is transparent in my navigator !
Is there a solution to change opacity of my image, without adding it on a colored background ?
It seems that imagecopymerge does not support the alpha (transparency) channel on images. Fortunately you can use a workaround with imagecopy to do it correctly. Here's a function to do this, taken from the comments on php.net:
function imagecopymerge_alpha($dst_im, $src_im, $dst_x, $dst_y, $src_x, $src_y, $src_w, $src_h, $pct){
// creating a cut resource
$cut = imagecreatetruecolor($src_w, $src_h);
// copying relevant section from background to the cut resource
imagecopy($cut, $dst_im, 0, 0, $dst_x, $dst_y, $src_w, $src_h);
// copying relevant section from watermark to the cut resource
imagecopy($cut, $src_im, 0, 0, $src_x, $src_y, $src_w, $src_h);
// insert cut resource to destination image
imagecopymerge($dst_im, $cut, $dst_x, $dst_y, 0, 0, $src_w, $src_h, $pct);
}

Merge two PNG images with PHP GD library

Does anybody have a script which can merge two PNG images?
With the following conditions:
Both images have transparent areas
The second image must have 50% opacity (it is overlaid over the first image)
Here is what I tried to do but without luck:
<?php
function imagecopymerge_alpha($dst_im, $src_im, $dst_x, $dst_y, $src_x, $src_y, $src_w, $src_h, $pct){
$cut = imagecreatetruecolor($src_w, $src_h);
imagecopy($cut, $dst_im, 0, 0, $dst_x, $dst_y, $src_w, $src_h);
imagecopy($cut, $src_im, 0, 0, $src_x, $src_y, $src_w, $src_h);
imagecopymerge($dst_im, $cut, $dst_x, $dst_y, 0, 0, $src_w, $src_h, $pct);
}
$image1 = imagecreatefrompng('a.png'); //300 x 300
$image2 = imagecreatefrompng('b.png'); //150 x 150
$merged_image = imagecreatetruecolor(300, 300);
imagealphablending($merged_image, false);
imagesavealpha($merged_image, true);
imagecopy($merged_image, $image1, 0, 0, 0, 0, 300, 300);
imagecopymerge_alpha($merged_image, $image2, 0, 0, 0, 0, 150, 150, 50);
header('Content-Type: image/png');
imagepng($merged_image);
?>
Edit:
First Image (left) and Second Image (right)
This is how it should be (left) and the result of my code (right)
The result of the solution proposed by dqhendricks
$image1 = imagecreatefrompng('a.png'); //300 x 300
$image2 = imagecreatefrompng('b.png'); //150 x 150
imagecopymerge($image1, $image2, 0, 0, 75, 75, 150, 150, 50);
this should be all you need. $image1 should hold the merged image where image2 has been overlayed with 50% opacity. the last argument is the alpha of the merged copy.
http://php.net/manual/en/function.imagecopymerge.php
$merged_image = imagecreatetruecolor(300, 300);
imagealphablending($merged_image, false);
imagesavealpha($merged_image, true);
imagecopy($merged_image, $image1, 0, 0, 0, 0, 300, 300);
// after first time of "imagecopy" change "imagealphablending"
imagealphablending($merged_image, **true**);
imagecopy($merged_image, $image2, 0, 0, 0, 0, 300, 300);

Categories