PHP GD: merge a blurry rectangle - php

I need to merge a blurry rectangle on another image (a white rectangle). I tried to imagesavealpha() but unfortunately the background of the rectangle remains black, and I want it with a gradient from red to white.
Here is my code:
<?php
$width = 200;
$height = 180;
$bw = $bh = 30;
$img1 = imagecreatetruecolor($width, $height);
$img2 = imagecreatetruecolor($width, $height);
$white = imagecolorallocate($img1, 255, 255, 255);
$red = imagecolorallocate($img2, 255, 0, 0);
imagefilledrectangle($img1, 0, 0, 100, 100, $white);
imagefilledrectangle($img2, 5, 5, 25, 25, $red);
imagefilter($img2, IMG_FILTER_GAUSSIAN_BLUR);
imagefilter($img2, IMG_FILTER_GAUSSIAN_BLUR);
imagefilter($img2, IMG_FILTER_GAUSSIAN_BLUR);
imagefilter($img2, IMG_FILTER_GAUSSIAN_BLUR);
imagefilter($img2, IMG_FILTER_GAUSSIAN_BLUR);
imagesavealpha($img2, true);
imagecopymerge($img1, $img2, 20, 20, 0, 0, $bw, $bh, 100);
header('Content-Type: image/png');
imagepng($img1);
imagedestroy($img1);
The restulting image is:

If you just want a blurred red rectangle on a white background your code can be simplified to this:
<?php
$width = 200;
$height = 180;
$img = imagecreatetruecolor($width, $height);
// fill with opaque white.
imagefill($img, 0, 0, 0x00ffffff);
// draw rectangle in opaque red.
imagefilledrectangle($img, 5, 5, 25, 25, 0x00ff00000);
for ($i = 0; $i < 5; $i++) {
imagefilter($img, IMG_FILTER_GAUSSIAN_BLUR);
}
header('Content-Type: image/png');
imagepng($img);
imagedestroy($img);
Result (of course the white background blends with the page background...):
If you want to be able to blend the red rectangle with any background colour (full alpha blending) then you might be out of luck. As far as I can tell IMG_FILTER_GAUSSIAN_BLUR doesn't support alpha values (I'm using PHP 7.0.3).

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);

How to use imagescale and retain appearance of edge "pixels"

So I have a 3x3 pixel image using imagecreate. I want to scale up the image with imagescale while maintaining the look of a 3x3 grid of "pixels". However, the pixels on the right and bottom edge are not the same size.
Here is my code and output image:
<?php
$image = imagecreate(3, 3);
imagecolorallocate($image, 0, 0, 255);
$red = imagecolorallocate($image, 255, 0, 0);
imagesetpixel($image, 0, 0, $red);
imagesetpixel($image, 1, 1, $red);
imagesetpixel($image, 2, 2, $red);
imagepng(imagescale($image, 200, 200, IMG_NEAREST_NEIGHBOUR));
header("Content-Type: image/png");
This is my output:
Notice how the bottom-right pixel is cut off. I kept playing with the numbers for the new dimensions and arrived at 256x256 at which point the pixels are all the same size.
This is the output after using 256x256:
My question is: How can I derive the dimensions to use for the resized image with the effect I described?
Bonus question: Is an alternative method which will allow me to resize to an arbitrary size and keep the pixels approximately the same size?
I would use imagecopyresampled to achieve this.
http://php.net/manual/en/function.imagecopyresampled.php
<?php
$width = 3;
$height = 3;
$image = imagecreate($width, $height);
imagecolorallocate($image, 0, 0, 255);
$red = imagecolorallocate($image, 255, 0, 0);
imagesetpixel($image, 0, 0, $red);
imagesetpixel($image, 1, 1, $red);
imagesetpixel($image, 2, 2, $red);
$new_width = 200;
$new_height = 200;
$dst = imagecreatetruecolor($new_width, $new_height);
imagecopyresampled($dst, $image, 0, 0, 0, 0, $new_width, $new_height, $width, $height);
imagepng($dst);
header("Content-Type: image/png");

Crop cirlcle image and merge with a marker with transparent bg

Im trying to crop a square image and merge it with a Marker, but i cant get the copped circle image to be transparent.
When is save the circle image as a PNG , it shows it OK with Transparent corners, but when i open it in Photoshop it has a White Color on the corners like the final image below.
here is the code im using:
//SAVED THE CIRCLE PNG IMAGE
$width = 320;
$height = 320;
$img1 = '';
switch($fileExt){
case '.png':
$img1 = ImageCreateFrompng($img= $image_config['new_image']);
break;
case '.jpg':
$img1 = ImageCreateFromjpeg($img= $image_config['new_image']);
break;
case '.gif':
$img1 = ImageCreateFromgif($img= $image_config['new_image']);
break;
}
$x=$width ;
$y=$height;
$img2 = imagecreatetruecolor($x, $y);
$bg = imagecolorallocate($img2, 255, 255, 255);
imagefill($img2, 0, 0, $bg);
$e = imagecolorallocate($img2, 0, 0, 0);
$r = $x <= $y ? $x : $y;
imagefilledellipse ($img2, ($x/2), ($y/2), $r, $r, $e);
imagecolortransparent($img2, $e);
imagecopymerge($img1, $img2, 0, 0, 0, 0, $x, $y, 100);
imagecolortransparent($img1, $bg);
header("Content-type: image/png");
imagepng($img1, './img/deviceImg/pin'.$datetime.'.png');
imagedestroy($img2); // kill mask first
imagedestroy($img1); // kill canvas last
//MERGING IT WITH THE PIN
$width = 320;
$height = 320;
$image_1 = imagecreatefrompng('./img/deviceImg/pin.png');
imagesavealpha($image_1, true);
imagealphablending($image_1, true);
$image_2 = imagecreatefrompng('./img/deviceImg/pin'.$datetime.'.png');
imagesavealpha($image_2, true);
imagealphablending($image_2, true);
imagecopy($image_1, $image_2, 40, 22, 0, 0, $width, $height);
imagepng($image_1, './img/deviceImg/pinASD'.$datetime.'.png');
Transparency is only copied with imagecopymerge(), not imagecopy(). So your penultimate line:
imagecopy($image_1, $image_2, 40, 22, 0, 0, $width, $height);
Should be changed to:
imagecopymerge($image_1, $image_2, 40, 22, 0, 0, $width, $height, 100);
Note the extra parameter (pct) at the end. As per the manual:
The two images will be merged according to pct which can range from 0 to 100. When pct = 0, no action is taken, when 100 this function behaves identically to imagecopy() for pallete images, except for ignoring alpha components, while it implements alpha transparency for true colour images.

Adding color to a white icon in PHP GD

I have a white icon (256x256) with a transparent background. Somehow, I want to be able to change the white icon, which has some transparent pixels in it (for anti-aliasing), to any RGB color.
I have tried using the following function but
imagefilter($im, IMG_FILTER_COLORIZE, 0, 255, 0)
Is there any way to do this in PHP GD? What functions can I look into?
I just created the following code and it works wonders.
Beware: If you set $backgroundTransparent to false, the image may lose quality when the background is painted under it.
<?php
$width = 256;
$height = 256;
$backgroundColor = array(0, 255, 0);
$backgroundTransparent = true;
$icon = imagecreatefrompng('Access-New.png');
imagealphablending($icon, false);
imagesavealpha($icon, true);
imagefilter($icon, IMG_FILTER_BRIGHTNESS, -255);
imagefilter($icon, IMG_FILTER_COLORIZE, 255, 0, 0);
if($backgroundTransparent == false) {
$background = imagecreatetruecolor($width, $height);
imagefill($background, 0, 0, imagecolorallocate($background, $backgroundColor[0], $backgroundColor[1], $backgroundColor[2]));
imagealphablending($icon, true);
imagecopy($background, $icon, 0, 0, 0, 0, $width, $height);
imagepng($background, NULL, 0, PNG_NO_FILTER);
}
else {
imagepng($icon, NULL, 0, PNG_NO_FILTER);
}
header("Content-type: image/png");
imagedestroy($background);
?>

center text in image

So I have an image, and I am writing text and a color box onto the image. It works but it's being added to the image in the top right corner, but I need it in the center of the image. I tried changing the x and y variables, but it only moves the text and not the white box.
Here is code
$image_filepath = './kenshin.jpg';
saveImageWithText("Welcome to Eureka!", $color, $image_filepath);
function saveImageWithText($text, $color, $source_file) {
$public_file_path = '.';
// Copy and resample the imag
list($width, $height) = getimagesize($source_file);
$image_p = imagecreatetruecolor($width, $height);
$image = imagecreatefromjpeg($source_file);
imagecopyresampled($image_p, $image, 0, 0, 0, 0, $width, $height, $width, $height);
// Prepare font size and colors
$text_color = imagecolorallocate($image_p, 0, 0, 0);
$bg_color = imagecolorallocate($image_p, 255, 255, 255);
$font = $public_file_path . '/arial.ttf';
$font_size = 12;
// Set the offset x and y for the text position
$offset_x = 0;
$offset_y = 20;
// Get the size of the text area
$dims = imagettfbbox($font_size, 0, $font, $text);
$text_width = $dims[4] - $dims[6] + $offset_x;
$text_height = $dims[3] - $dims[5] + $offset_y;
// Add text background
imagefilledrectangle($image_p, 0, 0, $text_width, $text_height, $bg_color);
// Add text
imagettftext($image_p, $font_size, 0, $offset_x, $offset_y, $text_color, $font, $text);
// Save the picture
imagejpeg($image_p, $public_file_path . '/output.jpg', 100);
// Clear
imagedestroy($image);
imagedestroy($image_p);
};
Here is output
Try this. It will help you…
<?php
$img = imagecreatefromjpeg("girl-hugging-the-globe.jpg"); // image.jpg is the image on which we are going to write text ,you can replace this iamge name with your
if(!$img) die("Unabe to load image");
$red = imagecolorallocate($img, 255, 0, 0);
$green = imagecolorallocate($img, 0, 255, 0);
$width = 600;// it will store width of image
$height = 100; //it will store height of image
$fontsize = 6; // size of font
$text = "Block Prints Online"; // Define the text
$pos = ( $width - imagefontwidth($fontsize)*STRLEN($text) );// calculate the left position of the text:
imagestring($img, $fontsize, 200, 150, $text, $red);
header('Content-type: image/jpeg');
imagejpeg($img);//it will output a jpeg image
imagedestroy($img);//it will destroy $img*/
?>

Categories