Transparent image on transparent image PHP - php

I'll explain a bit of my situation.
We got an island with cities. These could be:
Owned by my alliance
Owned by an enemy
Owned by nobody (free)
So we got 3 "cities"-images and an island image, looks like this:
Now we want to put these cities images on the island image. For example, we put a city owned by nobody on the island like this:
<?php
// Get image
$im = imagecreatefrompng('island.png');
imagealphablending($im,true);
// Get our "Free-city-position" image
$stamp = imagecreatefrompng('free.png');
$pos_x = 190 - 15; // Position X = 190 - the half of the free.png image = 30 / 2 = 15
$pos_y = 225 - 15;// Position Y = 225 - the half of the free.png image = 30 / 2 = 15
imagealphablending($stamp,true);
imagecopy($im, $stamp, $pos_x, $pos_y, 0, 0, imagesx($stamp), imagesy($stamp));
// Output image
header('Content-type: image/png');
imagepng($im);
imagedestroy($im);
?>
And now there is our problem: The city image is not transparent on the island image! It looks like this:
I thought imagealphablending should do the trick, but unfortunately, it doesn't.
How can we get the transparant city image on the island?

Taken from PHP's comment on GD functions :
If you are trying to copy a transparant image on to another image, you
might assume that you should apply the ImageAlphaBlending function to
the image that has the transparancy, the source image. In reality, you
must apply the ImageAlphaBlending function to the destination image.
Basically it's saying, "make the specified image respect
transparancy".

Try this way:
#!/usr/bin/php -f
<?php
// Read island image and get dimensions
$island=imagecreatefrompng("island.png");
$w_island=imagesx($island);
$h_island=imagesy($island);
// Read city image and get dimensions
$city= imagecreatefrompng("city.png");
$w_city=imagesx($city);
$h_city=imagesy($city);
// Create output image
$result=imagecreatetruecolor($w_island,$h_island);
imagesavealpha($result,true);
$transparent=imagecolorallocatealpha($result, 0, 0, 0, 127);
imagefill($result, 0, 0, $transparent);
// Splat island onto transparent background
imagecopy($result, $island, 0, 0, 0, 0, $w_island, $h_island);
// Splat city ontop
imagecopy($result, $city, 100, 280, 0, 0, $w_city, $h_city);
imagepng($result,"result.png");
?>

Related

PHP imagerotate is cropping image

I am writing a script that takes an arrow image and rotates it by a set number of degrees. Using the code below, when the angle is a multiple of 90 the image rotates and displays as expected.
The source image looks like this (74 x 74):
Images after rotating by 90:
Images after rotating by any other number (not a multiple of 90) eg 45:
As can be seen in the image, the tip of the arrow has been cropped out of the image. Could anyone please tell me why this is happening? Again, multiples of 90 are fine, it's just any other number where the unusual cropping occurs.
$props = ['w' => 74, 'h' => 74];
$angle = 360 - $_GET['angle'];
$final_img = imagecreatetruecolor($props['w'], $props['h']);
imagesavealpha($final_img, true);
$transColor = imagecolorallocatealpha($final_img, 0, 0, 0, 127);
imagefill($final_img, 0, 0, $transColor);
$rotate = imagecreatefrompng('arrow.png');
$src = imagerotate($rotate, $angle, $transColor); //rotated my image
$src_x = ImageSX($src); //find out new x width
$src_y = ImageSY($src); //find out new y height
$src_widthx = $src_x/2 - $props['w']/2; // divide each by 2 and then subtract desired end width from wider rotated width
$src_heighty = $src_y/2 - $props['h']/2; // and again for height
imagecopy($final_img, $src, 0, 0, $src_widthx, $src_heighty, $props['w'], $props['h']);
header('Content-Type: image/png');
imagepng($final_img);
When you rotate a square of nXm pixels by lets say 45 degrees you will get the diagonals(which are bigger than n or m and equal sqrt(n^2+m^2)) of the image be the new rotated image width and height.
The function crops the rotated image using the original dimensions of the image, namely n and m.
A way to fix the problem would be by crating a bigger blank image with the appropriate size, sqrt(width_original_image^2+height_original_image^2), and than copy the original image to the new image using imagecopy. After that you can use imagerotate on the new image
I installed and used the ImageMagick PHP library and the rotations show uncropped, no matter the degree of rotation.

PHP GD image merge changing my image to black

I have a very frustrating situation. I am using PHP GD for the first time, and it's been a bit of a rollercoaster relationship. Basically, I am trying to merge 2 images, a square one (with a height/width of x) onto a rectangle (with a width of x and a height of y).
The square needs to be centered vertically. But this isn't the issue - I've managed to position it correctly.
Whats happening is, my rectangle is white. My square has a white background, so when the images are merged, it should just look like my asset on a white rectangluar background.
When I merge the image though, GD is for some reason changing my background white rectangle to black - so you can see the white square in the middle, with black "bars" on top and bottom. Can anyone help?
Code is:
//create copy of original image to correct size
imagecopyresized($dst_image, $src_image, 0,0,0,0,$x_width,$x_height,$orig_img_x_width,$orig_img_x_height);
imagejpeg($dst_image, "resized_copy.jpg", 100);
$img = imagecreatetruecolor(1333, 2000);
$white = imagecolorallocate($img, 255, 255, 255);
imagefill ( $img, 0, 0, $white );
imagefilledrectangle($img,0,0,1333,2000, $white);
imagejpeg($img, "rectangle.jpg", 100);
//merge images
$dest2 = imagecreatefromjpeg("rectangle.jpg");
$src2 = imagecreatefromjpeg('resized_copy.jpg');
imagecopymerge($dest2, $src2, 0, 0, 0, -333.5, $x_width, $x_height, 100);
imagejpeg($dest2, "final_image.jpg", 100);
I've tried using imagecopy instead of imagecopymerge, but I get the same result. I'm sure there is a simple explanation, but I cant seem to find it trawling through the php manual.
I've read your question a few times but I'm not convinced I understand exactly what you are trying to achieve so I've made a few assumptions in producing the below code.
For the sake of simplicity I've created a 'square.jpg' test image file like so:
(Note that I've used small image sizes here so I can show them inline.)
// read in the square test image.
$square = imagecreatefromjpeg('square.jpg');
$square_x = imagesx($square); // 100px
$square_y = imagesy($square); // 100px
// create the rectangular image to merge with.
$rectangle = imagecreatetruecolor(100, 200);
$rectangle_x = imagesx($rectangle); // 100px
$rectangle_y = imagesy($rectangle); // 200px
// note that this isn't white, but rather a lovely shade of blue to better
// show the image on the white SO background!
$white = imagecolorallocate($rectangle, 128, 128, 255);
imagefill($rectangle, 0, 0, $white);
// merge the images.
imagecopymerge(
$rectangle,
$square,
0,
($rectangle_y / 2) - ($square_y / 2), // to vertically centre the square.
0,
0,
$square_x,
$square_y,
75 // Just to show the merge clearly; change back to 100 for your usage.
);
imagejpeg($rectangle, 'final_image.jpg', 100);
imagedestroy($rectangle);
imagedestroy($square);
This gives me the following image in final_image.jpg:

PHP - creating a PNG file with semi-transparent logo / watermark

I'm trying to place a logo into a white image and make it semi-transparent to be used as a watermark.
Here is my code...
// load the stamp and the photo to apply the watermark to
if (file_exists($logoPath)) {
$im = imagecreatefrompng($logoPath);
$size = getimagesize($logoPath);
$stamp = imagecreatetruecolor(612, 792);
imagefilledrectangle($stamp, 0, 0, 612-1, 792-1, 0xFFFFFF);
$sx = imagesx($stamp);
$sy = imagesy($stamp);
// center width and height
$centerX=$sx/2-$size[0]/2;
$centerY=$sy/2-$size[1]/2;
$res=imagecopymerge($stamp, $im, $centerX,$centerY, 0, 0, $sx, $sy, 15);
$waterPath = $watermark_path.$broker_id."_watermark.png";
// Save the image to file and free memory
imagepng($stamp, $waterPath);
imagedestroy($stamp);
imagedestroy($im);
}
It all looks good to me but when I run it I get this...
http://i43.tinypic.com/2cyft06.jpg
...as you can see, the lower right quad of the image is getting colored for some reason.
if you take a look at imagecopymerge() docs, the 7th and 8th arguments represent the source image width and height amount. You appear to pass the target image height (612, 792), so basically you're trying to copy a 612x792 slice from your logo image, which looks much smaller.
I'll try to better describe the arguments:
$res = imagecopymerge(
$stamp, // <- target image
$im, // <- source image, from where to copy (logo)
$centerX, // <- target x-position (where to place your logo),
$centerY, // <- target y-position
0, // <- source x-position (x-offset from where to start copy)
0, // <- source y-position
imagesx($im), // <- amount to copy from source (width)
imagesy($im), // <- amount... (height)
15 // <- i have no idea what this is :)
);

php add a picture onto another

I would like to change the color of an image with php.
if I wanted to make it appear redder applicherei an image on a higher level across an image with a transparent red and more or less high can indicate how the original photo should be red.
I can say gd php functions to create an image of a color (RGBA) and apply it to another image?
thanks :)
You can try using GD's imagecopymerge function, which copies one image to another and supports alpha transparency. Something like this should work:
<?php
$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);
?>
There's more information here.

Merging Images using GD with PHP

i'm working on creating one PNG image from two others.
Image A and B have the same dimensions, they are both 200x400px. The final image the same.
I'm using the GD library with PHP.
So my idea was to create a PNG-24 from my original PNG-8, then use color transparency and finally copy the second image into
this new PNG-24. The problem appears in the first step anyway, when going from PNG-24 to PNG-8 with color transparency:
This is to get the original PNG-8 and it's dimensions:
$png8 = imagecreatefrompng($imageUrl);
$size = getimagesize($imageUrl);
Now i create a new PNG and fill it's background with a green color (not present in the images):
$png24 = imagecreatetruecolor($size[0], $size[1]);
$transparentIndex = imagecolorallocate($png24, 0x66, 0xff, 0x66);
imagefill($png24, 0, 0, $transparentIndex);
This is for making the green color transparent:
imagecolortransparent($png24, $transparentIndex);
Then i copy the png8 into the PNG-24:
imagecopy($png24, $png8, 0, 0, 0, 0, $size[0], $size[1]);
So here's the problem: the original PNG-8 looks good, but it has a green border surrounding the shape within the original image. It's difficult to explain really. Seems like some part of the green background is left in the remaining PNG.
What can i do?
thanks in advance
best regards,
Fernando
I had some problems with png transparency before and was able to solve them with this pattern:
// allocate original image to copy stuff to
$img = imagecreatetruecolor(200, 100);
// create second image
$bg = imagecreatefrompng('bg.png');
// copy image onto it using imagecopyresampled
imagecopyresampled($img, $bg, 0, 0, 0, 0, 200, 100, 200, 100);
imagedestroy($bg);
// create third image
// do same routine
$fg = imagecreatefrompng('fg.png');
imagecopyresampled($img, $fg, 50, 50, 0, 0, 50, 50, 50, 50);
imagedestroy($fg);
// output image
imagepng($img);
imagedestroy($img);
I think the only difference between mine and yours is imagecopy() vs. imagecopyresampled(). I seem to remember having problems with that though it was quite a while ago. You can see an example of an image I use this pattern on here: http://www.ipnow.org/images/1/bggrad/bg4/yes/TRANSIST.TTF/8B0000/custombrowserimage.jpg (I allocate a blank image, copy the background image in, copy the overlay with transparency in)

Categories