positioning the watermark php GD - php

I want the watermark to go BELOW the image, so the overall height of image should expand.
Here is my code:
$img_width=imagesx($img);
$img_height=imagesy($img);
$watermark=imagecreatefrompng($watermark);
$watermark_width=imagesx($watermark);
$watermark_height=imagesy($watermark);
$image=imagecreatetruecolor($watermark_width, $watermark_height);
imagealphablending($image, false);
$dest_x=$img_width-$watermark_width-5;
$dest_y=$img_height-$watermark_height+1;
imagecopy($img, $watermark, $dest_x, $dest_y, 0, 0, $watermark_width, $watermark_height);
imagesavealpha($img, true);
I tried playing with watermark_width and height no luck.
Is this even possible?

You need to create an image with dimensions:
imagecreatetruecolor(max($img_width,$watermark_width), $img_height + $watermark_height + $margin);
then, copy the image to (0,0)
last, copy the watermark to (0,$img_height + $margin)
($margin is the space between image & watermark in pixels)
Edit:
$margin = 5;
$img = imagecreatefrompng($img_path);
$watermark = imagecreatefrompng($watermark_path);
$img_width = imagesx($img);
$img_height = imagesy($img);
$watermark_width = imagesx($watermark);
$watermark_height = imagesy($watermark);
$output_width = max($img_width, $watermark_width);
$output_height = $img_height + $watermark_height + $margin;
$output = imagecreatetruecolor($output_width, $output_height);
imagesavealpha($output, true);
imagealphablending($output, false);
imagerectangle($output, 0, 0, $output_width, $output_height, imagecolorallocatealpha($output, 0, 0, 0, 127));
imagecopy($output, $img, 0, 0, 0, 0, $img_width, $img_height);
imagecopy($output, $watermark, 0, $img_height + $margin, 0, 0, $watermark_width, $watermark_height);
imagepng($output, $path_to_save); // use null to output
imagedestroy($img);
imagedestroy($output);
imagedestroy($watermark);

Related

Image GD Resizing Issue

So I'm trying to take two large images (but later I'll be combinging 6 images in total), resize them to the x, y width, height I have taken from photoshop, and combine them into one 460 x 230 sized image.
This is the code I'm using
<?php
$dest = imagecreatefrompng('https://blzgdapipro-a.akamaihd.net/hero/ana/career-portrait.png');
$src = imagecreatefrompng('https://blzgdapipro-a.akamaihd.net/game/rank-icons/season-2/rank-6.png');
imagealphablending($dest, false);
imagesavealpha($dest, true);
imagealphablending($src, false);
imagesavealpha($src, true);
//imagescale($dest, 396, 161.92);
$some = imagecreate(460, 230);
$dest2 = resize($dest, 396, 162);
$src2 = resize($src, 79.19, 79.19);
//imagecopyresized($dest, $dest, 0, 0, 0, 0, 396, 161.92, 1098, 449);
imagecopyresized($src, $src, 10, 10, 0, 0, 79.19, 79.19, 256, 256);
//$img2 = imagecopymerge($dest, $src, 0, 0, 0, 0, 256, 256, 100); //have to play with these numbers for it to work for you, etc.
imagecopymerge($dest2, $src2, 0, 0, 0, 0, 460, 230, 50);
header('Content-Type: image/png');
imagepng($dest, 'merged2.png');
imagepng($dest2);
//file_put_contents('merged.png', $contents);
imagedestroy($dest);
imagedestroy($src);
imagedestroy($some);
imagedestroy($dest2);
imagedestroy($src2);
imagedestroy($img2);
//imagedestroy($then);
function resize($img, $width, $height, $stretch = false)
{
$temp = imagecreatetruecolor($width, $height);
imagealphablending($temp, true);
imagesavealpha($temp, true);
$bg = imagecolorallocatealpha($temp, 0, 0, 0, 0); // Background color
imagefill($temp, 0, 0, $bg);
if ($stretch)
{
imagecopyresampled($temp, img, 0, 0, 0, 0, $width, $height, imagesx($img), imagesy($img));
}
else
{
if (imagesx($img) <= $width && imagesy($img) <= $height)
{
$fwidth = imagesx($img);
$fheight = imagesy($img);
}
else
{
$wscale = $width / imagesx($img);
$hscale = $height / imagesy($img);
$scale = min($wscale, $hscale);
$fwidth = $scale * imagesx($img);
$fheight = $scale * imagesy($img);
}
imagecopyresampled($temp,
$img,
($width - $fwidth) / 2, ($height - $fheight) / 2,
0, 0,
$fwidth, $fheight,
imagesx($img), imagesy($img)
);
}
return $temp;
}
The issue is that the image rendered is very faded
because of this line:
imagecopymerge($dest2, $src2, 0, 0, 0, 0, 460, 230, 50);
If I change the 50, which is the PCT value to 100, it shows one image with a black background (masking the other image), but if I change it to 0, it shows only the other image with a black background (masking the other image)
If the value is either 0 or 100, the image shown is at its full color though. How do I merge these 2 images together while preserving their transparency and vibrancy of color?
Instead of imagecopymerge use imagecopy. You also always need to correctly specify the dimensions of the source image when copying:
$dest = imagecreatefrompng('https://blzgdapipro-a.akamaihd.net/hero/ana/career-portrait.png');
$src = imagecreatefrompng('https://blzgdapipro-a.akamaihd.net/game/rank-icons/season-2/rank-6.png');
$dest2 = resize($dest, 396, 162);
imagedestroy($dest);
$src2 = resize($src, 79, 79); // should be int not float.
imagedestroy($src);
// the last 2 params must match the width/height of the $src2 image.
imagecopy($dest2, $src2, 0, 0, 0, 0, 79, 79);
imagedestroy($src2);
header('Content-Type: image/png');
imagepng($dest2);
imagedestroy($dest2);
You don't need to change the alpha settings on $dest or $src because they aren't being rendered - you render the new image resource created in, and returned by, your resize function. Because of this you do need to slightly change the function:
function resize($img, $width, $height, $stretch = false)
{
$temp = imagecreatetruecolor($width, $height);
imagealphablending($temp, false); // changed to false.
imagesavealpha($temp, true);
...
Edit:
You might be better off simply using the imagescale function instead of using your own resize function:
$dest = imagecreatefrompng('https://blzgdapipro-a.akamaihd.net/hero/ana/career-portrait.png');
$src = imagecreatefrompng('https://blzgdapipro-a.akamaihd.net/game/rank-icons/season-2/rank-6.png');
$dest2 = imagescale($dest, 396);
imagealphablending($dest2, false);
imagesavealpha($dest2, true);
$src2 = imagescale($src, 79);
imagecopy($dest2, $src2, 0, 0, 0, 0, 79, 79);
header('Content-Type: image/png');
imagepng($dest2);
imagedestroy($dest);
imagedestroy($src);
imagedestroy($dest2);
imagedestroy($src2);

Unwanted dashed black border when rotating image in php

I am getting unwanted dashed black border when I rotate an image. I have tried to remove that but I am not finding any success. I am using the following function for image rotation. I try to preserve transparency. I have provided a image as well.
Here is an Image URL: http://s23.postimg.org/hep2pkol7/border.png
function imageRotation ($source, $rotang)
{
imagealphablending($source, false);
imagesavealpha($source, true);
$rotation = imagerotate($source, $rotang, imageColorAllocateAlpha($source, 0, 0, 0, 127));
imagealphablending($rotation, false);
imagesavealpha($rotation, true);
return $rotation;
}
I call the function something like that:
$rotatedImage = imageRotation($image, 10);
Here is the full code
<?php
// Some settings
$text = "Previously blogging";
$fontFace = 'Days.ttf';
$fontSize = 90;
$angle = 0;
$bbox = calculateTextBox($text, $fontFace, $fontSize, $angle);
$image = imagecreatetruecolor($bbox['width'], $bbox['height']);
// Define some colors
$black = imagecolorallocate($image, 0, 0, 0);
$yellow = imagecolorallocate($image, 0xFF, 0xFF, 0xFF);
//Fill the image with background color
imagefill($image, 0, 0, $yellow);
// Draw text
imagettftext($image, $fontSize, $angle, $bbox['left'], $bbox['top'], $black, $fontFace, $text);
$image = imageRotation($image, 20);
$im = imagecreatefromjpeg('weight-loss.jpg');
// Switch antialiasing on for one image
imageantialias($im, true);
$destWidth = imagesx($im);
$destHeight = imagesy($im);
$src_w = imagesx($image);
$src_h = imagesy($image);
$dst_x = ($destWidth - $src_w)/2;
$dst_y = ($destHeight - $src_h)/2;
imagecopy($im, $image, $dst_x, $dst_y, 0, 0, $src_w, $src_h);
header ('Content-Type: image/jpeg');
imagejpeg($im, null, 100);
imagedestroy($im);
imagedestroy($image);
function calculateTextBox($text,$fontFile,$fontSize,$fontAngle)
{
$rect = imagettfbbox($fontSize,$fontAngle,$fontFile,$text);
$minX = min(array($rect[0],$rect[2],$rect[4],$rect[6]));
$maxX = max(array($rect[0],$rect[2],$rect[4],$rect[6]));
$minY = min(array($rect[1],$rect[3],$rect[5],$rect[7]));
$maxY = max(array($rect[1],$rect[3],$rect[5],$rect[7]));
return array(
"left" => abs($minX),
"top" => abs($minY),
"width" => $maxX - $minX,
"height" => $maxY - $minY,
"box" => $rect
);
}
function imageRotation ($source, $rotang)
{
imagealphablending($source, false);
imagesavealpha($source, true);
$rotation = imagerotate($source, $rotang, imageColorAllocateAlpha($source, 0, 0, 0, 127), 0);
imagealphablending($rotation, false);
imagesavealpha($rotation, true);
return $rotation;
}
?>
This is neither a dashed border, nor a border at all actually. This happens because your images are low-resolution, what cause the the rotated borders to "break", because actual pixels don't rotate.
That's what I'm trying to explain:
A line, parallel to the "pixel construction"; one px is three dashes long:
-------------------------------------
It would look smooth.
Rotated line:
---
---
---
---
---
---
---
As you see, due to low resolution, it steps, not smoothly goes down.
If you use the higher resolution, the issue would go away. The visual effect of the "black" border appears because your white image contrasts with the other part of image.

Extend canvas around image

I've got this code. My problem, that it doesn't work correctly. It extends canvas around image, but image "deformed". I don't know where is it the problem?!
$width = 100;
$height = 80;
//$source_width = 50;
//$source_height = 30;
if ($width > $source_width AND $height > $source_height)
{
$width_new = $width;
$height_new = $height;
$dst_x = ($width - $source_width)/2;
$dst_y = ($height - $source_height)/2;
}
$img = imagecreatetruecolor($width, $height);
$white = imagecolorallocate($img, 255, 255, 255);
imagefill($img, 0, 0, $white);
imagecopyresampled($img, $source_image, $dst_x, $dst_y, 0, 0, $width_new, $height_new, $source_width, $source_height);
Your destination height and width are larger than the source height and width. Make them the same.
You should only use the larger height and width for the canvas (the white)
For example:
imagecopyresampled($img, $source_image, $dst_x, $dst_y, 0, 0, $width_new, $height_new, $source_width, $source_height);
Should be:
imagecopyresampled($img, $source_image, $dst_x, $dst_y, 0, 0, $source_width, $source_height, $source_width, $source_height);

Transparency of PHP merged image not working

I'm creating an image with imagecopymerge, but the image being overlaid on top, is a PNG but the transparent part is pure white. How do I enable transparency?
$image = imagecreatefromjpeg($this->getFile());
$size = getimagesize($this->getFile());
$watermark = imagecreatefrompng('../watermark.png');
$watermark_width = imagesx($watermark);
$watermark_height = imagesy($watermark);
$dest_x = $size[0] - $watermark_width - 10;
$dest_y = $size[1] - $watermark_height - 5;
//die($watermark_width);
$thumb_image = imagecreatetruecolor($this->getThumbWidth(), $this->getThumbHeight());
imagealphablending($thumb_image,true);
imagealphablending($image,true);
imagecopymerge($image, $watermark, $dest_x, $dest_y, 0, 0, $watermark_width, $watermark_height, 100);
imagecopyresampled( $thumb_image, $image, 0, 0, 0, 0, $this->getThumbResizeWidth(), $this->getThumbResizeHeight(), $this->getWidth(), $this->getHeight() );
imagejpeg( $thumb_image, $this->getThumbDestination(), $this->getThumbQuality() );
imagedestroy($thumb_image);
imagedestroy($image);
So I FINALLY found a solution. It's using imagecopy().
Here is the article that nudged me in the right direction.
That took quite a few hours of research!
Use imagecolortransparent()
Read more here
EDIT:
A better solution is here:
https://stackoverflow.com/a/313103/1533203

PHP GD transparency doesn't work with iPhone

I am using code to create an image with PHP GD that needs a fully transparent background. When I create it, it displays fine in a browser, but bad in my iPhone app. I don't know why, but in my iPhone it displays all transparency with black. This seems to be a GD problem because when I loaded my GD image into a web editor and reexported it, it displayed fine in my iPhone app. Is there a special way I should export the png image from GD or something or is this some sort of bug? Here is the code:
$filename = "./me.jpg";
$image_s = imagecreatefromjpeg($filename);
list($current_width, $current_height) = getimagesize($filename);
$left = isset($_GET['pl']) ? abs($_GET['pl']) : 0;
$top = isset($_GET['pt']) ? abs($_GET['pt']) : 0;
$width = isset($_GET['cs']) ? abs($_GET['cs']) : 65;
$height = isset($_GET['cs']) ? abs($_GET['cs']) : 65;
$canvas = imagecreatetruecolor($width, $height);
$current_image = imagecreatefromjpeg($filename);
imagecopy($canvas, $current_image, 0, 0, $left, $top, $current_width, $current_height);
$newwidth = 65;
$newheight = 65;
$image = imagecreatetruecolor($newwidth, $newheight);
imagealphablending($image, true);
imagecopyresampled($image, $canvas, 0, 0, 0, 0, $newwidth, $newheight, $width, $height);
$mask = imagecreatetruecolor($newwidth, $newheight);
$transparent = imagecolorallocate($mask, 255, 255, 255);
imagecolortransparent($mask, $transparent);
imagefilledellipse($mask, $newwidth / 2, $newheight / 2, $newwidth, $newheight, $transparent);
$red = imagecolorallocate($mask, 0, 0, 0);
imagecopymerge($image, $mask, 0, 0, 0, 0, $newwidth + 10, $newheight + 10, 100);
imagecolortransparent($image, $red);
imagefill($image,0,0, $red);
header('Content-type: image/png');
imagepng($image);
imagedestroy($image);
imagedestroy($mask);
Have you tried using imagesavealpha instead of imagesettransparency? Set alpha blending to false and then use imagesavealpha to true. Finally you'll call the imagecolorallocatealpha function to get your transparent/alpha color instead of imagesettransparency:
imagealphablending($image, false);
imagesavealpha($image, true);
$transparent = imagecolorallocatealpha($image, 255, 255, 255, 127);
imagefilledellipse($mask, $newwidth / 2, $newheight / 2, $newwidth, $newheight, $transparent);
etc...

Categories