PHP merging two images creates a pink shade - php

I am trying to merge two images using PHP code below:
$image1=imagecreatefrompng($url1);
$image2=imagecreatefrompng($url2);
$final = imagecreatetruecolor($w, $h);
$backgroundColor = imagecolorallocate($final, 255, 255, 255);
imagefill($final, 0, 0, $backgroundColor);
imagecopy($final, $image1, 0,0,0,0,$w,$h);
imagecopy($final, $image2, 0,0,0,0,$w,$h);
After merging, I get a pink shade on the generated images. Please help. How can I resolve it?
Original images:
Resulting merged image:

Your target image is GIF, which is limited to a 256 colour palette. Try exporting as JPG or PNG and you'll probably get better colour fidelity.

I have tried your code using your image link
and its works well and generates appropriate png
For your reference
$url1 = 'http://i.stack.imgur.com/kDYTM.png';
$url2 ='http://i.stack.imgur.com/MKTcb.png';
$image1=imagecreatefrompng($url1);
$image2=imagecreatefrompng($url2);
$final = imagecreatetruecolor(275, 275);
$backgroundColor = imagecolorallocate($final, 255, 255, 255);
imagefill($final, 0, 0, $backgroundColor);
imagecopy($final, $image1, 0,0,0,0,275,275);
imagecopy($final, $image2, 0,0,0,0,275,275);
header('Content-type:image/png');
imagepng($final);
For gif image you can replace last two line with
header('Content-type:image/gif');
imagegif($final);

Related

"z-index" in php GD

In css, we have a property called "z-index", what is the same in PHP GD and Image Functions to control the "z-index"?
I've been searching but I can't find one, please help.
Thankyou
there nothing existing like z-index in php GD library
but there several ways to overlap image over image or text over image
$redimg = imagecreatetruecolor(100, 100);
$image = imagecreatefrompng('image.png');
// sets background to red
$red = imagecolorallocate($redimg, 255, 0, 0);
imagefill($redimg, 0, 0, $red);
// Merge the red image onto the PNG image
imagecopymerge($image, $redimg, 0, 0, 0, 0, 100, 100, 75);
header('Content-type: image/png');
imagepng($image);
imagedestroy($image);
imagedestroy($redimg);
here one example, or let me know, what exactly you trying to do, I will help you
There's more information here.

PHP imagecopyresampled() produces image border on one side

I have a resampling script that centers resampled images on a square canvas.
For horizontally-oriented images that are centered vertically on a white background a line is added along the BOTTOM edge of the resampled image.
For vertically-oriented images that are centered horizontally the line appears on the RIGHT edge of the resampled image.
$thumb = imagecreatetruecolor($th_width, $th_height);
imagecopyresampled($thumb, $source, $th_x, $th_y, 0, 0, $th_width, $th_height, $src_width, $src_height);
$bgcolor = imagecolorallocate($thumb, 255, 255, 255);
imagefill($thumb, 0, 0, $bgcolor);
The line is there regardless of background fill, it just shows up most on white.
What causes this? No amount of adjusting parameter values will get rid of it (they just offset the resampled image on the background or distort it).
I am providing my own workaround for this issue.
It appears the image border artifact is a COMBINATION result of 'imagecopyresampled()' AND centering offsets. If I just resample the image as-is THEN center and fill the image, the border is avoided. Here is the workaround:
1) RESAMPLE your image as-is (same aspect ratio) then SAVE to retain changes:
$thumb = imagecreatetruecolor($res_width, $res_height);
imagecopyresampled($thumb, $source, 0, 0, 0, 0, $res_width, $res_height, $src_width, $src_height);
// SAVE new image - set quality to lossless since reusing it:
imagejpeg($thumb, "resampled/output_temp.jpg", 100);
2) Retrieve the temporary image:
$file = "resampled/output_temp.jpg";
$image = file_get_contents($file);
$source = imagecreatefromstring($image);
// Get the RESAMPLED image dimensions
list($src_width, $src_height) = getimagesize($file);
3) NOW apply CENTERING and FILL:
$thumb = imagecreatetruecolor($th_width, $th_height);
// COPY the image
imagecopy($thumb, $source, $th_x, $th_y, 0, 0, $src_width, $src_height);
$bgcolor = imagecolorallocate($thumb, 255, 255, 255);
// Replace default black background - this must be placed AFTER imagecopy()
imagefill($thumb, 0, 0, $bgcolor);
// Save image (uses default quality setting 75)
imagejpeg($thumb, "resampled/" . $newfile);
// Optionally free up memory:
imagedestroy($thumb);
The result is a clean image.
For correcting incomplete imagefill() on the background when centering vertically-oriented images see this post:
imagecopyresampled() results in split color background imagefill()

Create a tiled image with offset

In the process of creating a tiled image I'd like to set an offset (so that the tile doesn't start at 0, 0) but when I provide what I'd expect to give me the correct image, it's not rendered correctly.
I'm setting the tile using imagesettile($image, $tile); but when I go to draw it (using imagefilledrectangle($image, 10, 10, 300, 300, IMG_COLOR_TILED);), I get an image as though it was tiled from 0, 0 (with the top & left 10 pixels black) instead of it being tiled from 10, 10.
Any ideas as to how I can get it tiled from 10, 10 or do I have to create another tiled image and copy it across?
In the end I had to create a new image which was tiled and copy it in. The final code is along the lines of:
$transparent = imagecolorallocatealpha($background_image, 255, 255, 255, 127);
$tiled_image = imagecreatetruecolor($width, $height);
imagefill($tiled_image, 0, 0, $transparent);
imagesettile($tiled_image, $tile);
imagefilledrectangle($tiled_image, 0, 0, $width, $height, IMG_COLOR_TILED);
imagecopyresampled($image, $tiled_image, $sx, $sy, 0, 0, $ex, $ey, $width, $height);

PHP GD : Can i just fill transparent part?

There is an image which has transparent area. (png image)
Now, while doing a imagecopy, can we just fill that transparent area?
Imagemagick can do this easily. Is that possible in php gd?
A layered approach via imagecopymerge() is one route. The concept is to merge your source image onto a new image, with a pre-set background image, which will show through the source image's transparency once merged.
//create main image - transparent, with opaque red square in middle
$img = imagecreate(60, 60);
$white = imagecolorallocate($img, 255, 255, 255);
imagecolortransparent($img, $white); //make background transparent
$red = imagecolorallocate($img, 255, 0, 0);
imagefilledrectangle($img, imagesx($img) / 4, imagesy($img) / 4, imagesx($img) - (imagesx($img) / 4), imagesy($img) - (imagesy($img) / 4), $red);
//create new image, with pre-filled background, then merge first image across
$img2 = imagecreate(60, 60);
$blue = imagecolorallocate($img2, 0, 0, 255);
imagecopymerge($img2, $img, 0, 0, 0, 0, imagesx($img), imagesy($img), 100);
//output
imagepng($img2);
So the first image creates a transparent image (the white) with a red square in the middle. The second image is simply a blue fill.Merge the two, and the blue shows through the transparent part of the first image, so our red square now sits on the blue fill. Effectively, we've filled the transparent part.
Here's the three states in sequence.
There is nothing to 'fill' where there is transparency. Transparency in a png (or gif) is not the absence of a color, but a single color specifically marked to be shown as transparent. Therefore you want to remove that marker.
Take a look at the php gds function 'imagecolortransparent':
Nope, you can't.
Instead that, you can try to create a copy from a colored rectangle. This code worked for me:
$input = imagecreatefrompng($file_input);
list($width, $height) = getimagesize($file_input);
$output = imagecreatetruecolor($width, $height);
$white = imagecolorallocate($output, 255, 255, 255);
imagefilledrectangle($output, 0, 0, $width, $height, $white);
imagecopy($output, $input, 0, 0, 0, 0, $width, $height);
imagepng($output, $file_output);

Merge images with PHP

I have written a code for merge two images.
My code is:
$rnd = rand("99000", "99999");
$dst_path = "/home/maxioutl/public_html/images/urunler/";
$dst_file_name = "tresim-{$rnd}.jpg";
$dst_file = $dst_path.$dst_file_name;
$dst = imagecreatetruecolor(250, 375);
imagefill($dst, 0, 0, imagecolorallocate($dst, 255, 255, 255));
$src = imagecreatefromjpeg("http://www.goldstore.com.tr/upload/product/raw/3.72925.0332.JPG");
imagecopymerge($dst, $src, 40, 60, 0, 0, 250, 375, 100);
imagejpeg($dst, $dst_file, 90);
Result:
Black background. Where is it?
It's the imagecopymerge($dst, $src, 40, 60, 0, 0, 250, 375, 100); statement that's doing it.
You're passing it the dimensions 250x375, which isn't the watch's actual dimensions. Therefore the merge bounding box continues on and it uses black. You can see this easily if you comment it out because you'll get your white square from the fill like you were expecting.
you need to get the exact dimensions of your watch graphic (i.e. through getimagesize) and pass those to imagecopymerge so it cuts it exactly when it merges.
$arrSize = getimagesize($originalFile);
imagecopymerge($dst, $src, 40, 60, 0, 0, $arrSize[0], $arrSize[1], 100);
The code you wrote superimposes the images. It does not remove the white pixels from the image with the watch.
They are basically overlapped.
You should cycle through both image dimensions and replace each *white pixel with a black pixel or a transparent pixel.
*white pixel may not necessarily mean rgb(255,255,255) you can choose to treat all pixels with rgb(>235,>235,>235) as being "white".
Function imagecreatetruecolor creates completely black image
Taken from here :
imagecreatetruecolor() returns an image identifier representing a
black image of the specified size.

Categories