Merge two PNG images with PHP. Output image CHANGES and wrong opacity - php

I need to merge the following images, however my solution is not working.
My code is the following (I pass the URL of the images to the script via GET parameter)
<?php
$dest = imagecreatefrompng($_GET['img1']);
$src = imagecreatefrompng($_GET['img2']);
imagecopymerge($dest, $src, 0, 0, 0, 0, 1500, 1500, 50);
$white = imagecolorallocate($dest, 255, 255, 255);
imagecolortransparent($dest, $white);
header('Content-Type: image/png');
imagepng($dest);
?>
Both image are PNG with transparent background and both are 1500x1500.
First image:
Second image:
What I get:
Why can't I make the final image have the right opacity? I tried changing the last value of imagecopymerge() to 0 or 100 but in those cases I only get one image or another. I need them both, exactly overlapped on one another!
Also, if you look carefully around the gem in the final image, there is some extra blue color... how is this possible?

This is caused by setting the resulting image to use image transparency rather than per-pixel alpha-channel transparency by your call to imagecolortransparent which sets any white (#ffffff) pixels to 100% transparent.
The artefacts ('extra blue colour' and edge pixels) on the resulting image are caused by the alpha-channel transparency from the original images not being saved and the pixels (which were 100% transparent but not white) showing their original colour.
The 'washed out' look of your result comes from telling imagecopymerge to merge the two images with 50% transparency.
The solution is to use the correct alpha settings:
<?php
$dest = imagecreatefrompng($_GET['img1']);
$src = imagecreatefrompng($_GET['img2']);
imagesavealpha($dest, true);
imagecopy($dest, $src, 0, 0, 0, 0, 1500, 1500);
header('Content-Type: image/png');
imagepng($dest);

Related

PHP imagecolorallocate not working

I am running a site off of BlueHost, with PHP 5.4, and GD Version bundled (2.0.34 compatible) - a high enough GD to use imagecreatetruecolor()
I am cropping an image, and sometimes the cropped image does not entirely fill the output thumb. imagecreatetruecolor() leaves it with a black background wherever the resampled image isn't covering the output thumb, as shown below
but I would like it to be a WHITE, or TRANSPARENT background.
PHP:
$tci = imagecreatetruecolor($w, $h);
$color = imagecolorallocate($tci, 255, 255, 255);
imagefill($tci, 0, 0, $color);
imagecopyresampled($tci, $img, 0, 0, $x, $y, $w, $h, $wOr, $hOr);
imagejpeg($tci, $preview, $qual);
I am not having an issue with resampling the image, or using imagecreatetruecolor(), but for whatever reason, I cannot get the background color to white.
Thank you in advance.
EDIT
If I comment out the line
imagecopyresampled(...)
then it gives the correct background color that I set in imagecolorallocate and image fill. It's the imagecopyresampled that's causing the problem.

GD2 - Copying two transparent images results in black background

This is blowing my mind. I want to merge 2 transparent PNGs.
One is a circle ($source) generated on the fly from a square image.
The second is a map marker ($marker) with a transparent circle to fit the first behind.
imagepng($source); and imagepng($marker); outputs just as one might expect.
With transparent backgrounds.
I then create an empty transparent image the size of the marker to place them both together:
//NEW BLANK TRANSPARENT IMAGE
$dest = imagecreatetruecolor(50, 61);
$transparent = imagecolorallocatealpha($dest, 0, 0, 0, 127);
imagefill($dest, 0, 0, $transparent);
imagealphablending($dest, true);
imagesavealpha($dest,true);
//COPY THE CIRCLE
imagecopy($dest, $source, 5, 5, 0, 0, 41, 41);
//AND THE MARKER ON TOP
imagecopy($dest, $marker, 0, 0, 0, 0, 50, 61);
In the result, the circle appears as a black square with the circle inside.
I tried a lot of combinations of imagealphablending and imagesavealpha both on $source and $dest and nothing seems to work.
How can I remove the black square and leave the $source transparent in the result as it is before the merge?
The problem here was:
To generate the circle on the fly, I was creating a circular mask and making everything else transparent making it red and then making red transparent.
This is incompatible with imagesavealpha(true) as it says the gd engine exactly to ignore transparent colors and save the whole alpha channel instead.
When merging both images, the color once transparent is now black.
The solution to my case was to analise it pixel per pixel and copy it to a blank image if it's inside the circle using the circular equation.

Why does this transparent PNG cause borders when combined using GD?

I am trying to create an image from an another image using PHP. Here is my code:
<?php
$width = 109;
$height = 109;
$image = imagecreatetruecolor($width, $height);
$source_under = imagecreatefrompng('ecloid_under.png');
$black = imagecolorallocate($image, 0x00, 0x00, 0x00);
imagecolortransparent($image, $black);
imagecopy($image, $source_under, 0, 0, 0, 0, $width, $height);
header('Content-type: image/png');
imagepng($image);
imagedestroy($image);
?>
So I am loading this image in $source_under
and copying it over a transparent blank "canvas" image. Here is the result of that operation:
As can be seen, there is a sort of black border around the whole initial image. I think this is due to the fact that initially, the "canvas" image is all black. So there is something wrong with the transparency and the anti-aliasing of the image.
This isn't the first time I have a similar problem, but last time the source image was the cause. This time around, opening it in Photoshop does not show any potential problems with it.
Does anyone know how to fix this?
Can you try to enable alpha blending on $image before you copy the original to it:
imagealphablending($image, true);
Second try would be to create a transparent color and to fill $image with that color before the copy.
$transparent = imagecolorallocatealpha($image, 0, 0, 0, 127);
imagefill($image, 0, 0, $transparent);
imagealphablending($image, true);
You have partial transparency around the edges of your source image. That makes it combine with the black of the canvas image (which you normally can't see because it's 100% transparent), giving the results you see. You could avoid this by making sure your entire alpha channel on the source image is either 100% or 0%, or by choosing a more appropriate base color for your canvas image (i.e. one that matches the background color scheme of your site).
Fabio Anselmo's comment would help in that GIFs don't have a real alpha channel -- GIF transparency is all-or-nothing -- so saving as one will accomplish the 100%-or-0% solution. Unless you're extremely careful it will also give you a "border" right there in the source image -- made up of whatever background color you have or select in the GIF conversion -- as a result of your image's antialiasing. (However, the interlacing part is irrelevant.)

Alphabet border in transparent background image is unwanted?

I am using this code to creating images with text written in it with transparent backgrounds.
<?php
// Set the content-type
header('Content-Type: image/gif');
// Create the image
$im = imagecreatetruecolor(400, 150);
// Create some colors
$black = imagecolorallocate($im, 0, 0, 0);
$acolor = imagecolorallocate($im, 153, 204, 153);
imagecolortransparent($im, $black);
// The text to draw
$text = 'Testing...';
// Replace path by your own font path
$font = 'arial.ttf';
// Add the text
imagettftext($im, 50, 0, 10, 100, $acolor, $font, $text);
// Using imagegif()
imagegif($im,"img.gif");
imagedestroy($im);
?>
But text which is written in img.gif has some unwanted color(Black) on borders of alphabets('e,s,n,g'). How can i finish that color.The generated image is
The arial font download site is http://code.google.com/p/ireader/downloads/detail?name=arial.ttf
The GIF format cannot handle alpha transparency. It can have only 100% transparent (= invisible), or 100% opaque (= visible) pixels.
Your text seems to have anti-aliased, soft edges.
Those edges aren't 100% transparent, but they're also not 100% opaque - they are a mixture of foreground and background. That makes them appear softer.
Because the GIF format can't deal with these nuances, the library uses a mixture of green and black to simulate a "weaker" green.
If you use the PNG format, the problem should go away: PNG supports alpha transparency. There are some issues that you need to look into if you still need to support IE6, but for every other browser, this will work fine straight away.

How to combine image and text on the fly in php

i want to combine text and image on the fly to create a jpg widget. I want to do this for a fundraising website, i will need to update the image once a day so it reflect the updated fundraising progress bar. The reason why i want a jpg (image) widget is because it is much more friendly to add to blogs, website etc.
you can do it with gd
//open up the image you want to put text over
$im = imagecreatefromjpeg($imagePath);
//The numbers are the RGB values of the color you want to use
$black = ImageColorAllocate($im, 255, 255, 255);
//The canvas's (0,0) position is the upper left corner
//So this is how far down and to the right the text should start
$start_x = 10;
$start_y = 20;
//This writes your text on the image in 12 point using verdana.ttf
//For the type of effects you quoted, you'll want to use a truetype font
//And not one of GD's built in fonts. Just upload the ttf file from your
//c: windows fonts directory to your web server to use it.
Imagettftext($im, 12, 0, $start_x, $start_y, $black, 'verdana.ttf', 'text to write');
//Creates the jpeg image and sends it to the browser
//100 is the jpeg quality percentage
Imagejpeg($im, '', 100);
ImageDestroy($im);
I'd suggest you look into Imagemagick.
http://php.net/manual/en/book.imagick.php

Categories