PHP GD: Blur for transparent image - php

I am trying to create the silhouette of PNG image with transparencies.
Here is my code
//file that i am working with
$file='http://www.google.com/mapfiles/turkey.png';
$im =imagecreatefrompng($file);
imagealphablending($im, false);
imagesavealpha($im, true);
$imw =imagesx($im);
$imh =imagesy($im);
//turkey body color
$bodycolor=imagecolorallocatealpha($im, 144, 144, 144, 50);
//imageholder
$imnew =imagecreatetruecolor($imh, $imh);
imagealphablending($imnew, false);
imagesavealpha($imnew, true);
$transparent_color=imagecolorallocatealpha($imnew, 0, 0, 0, 127);
imagecolortransparent($imnew, $transparent_color);
imagefilledrectangle($imnew, 0, 0, $imh, $imh, $transparent_color);
for ($i=0; $i > 24;
//all not transparent pixels are copied to imageholder
if ($alpha != 127)
{
imagesetpixel($imnew, $i, $j, $bodycolor);
}
}
}
//blur filter
imagefilter($imnew, IMG_FILTER_GAUSSIAN_BLUR);
imagefilter($imnew, IMG_FILTER_GAUSSIAN_BLUR);
imagefilter($imnew, IMG_FILTER_GAUSSIAN_BLUR);
header ("Content-type: image/png");
imagepng ($imnew);
imagedestroy ($imnew);
?>
So, I need to get the silhouette ot the turkey with blurred edges. I need edges to be blurred "outside", so the farther the pixel was from edge, the more transparent it was with the same rbg. And imagefilter also lifts the turkey a bit :)

For more complex image manipulations like these, I would highly recommend you use ImageMagick: http://www.imagemagick.org
It's pretty easy to install unto your server, very fast and has great documentation. They have a whole section for what you're talking about: http://www.imagemagick.org/Usage/channels/

Related

I'm trying to make a image transparent using GD library from PHP but running following code, only a portion will be transparent

I'm trying to make a image transparent using GD library from PHP but running following code, only a portion will be transparent.
$image = imagecreatefrompng("$second");
imagealphablending($image, false);
$col_transparent = imagecolorallocatealpha($image, 0, 0, 0, 127);
imagefill($image, 0, 0, $col_transparent); // set the transparent colour as the background.
imagecolortransparent ($image, $col_transparent); // actually make it transparent
imagesavealpha($image, TRUE);
header( 'Content-Type: image/png' );
imagepng($image);
Here you have original image: https://postimg.org/image/y68nw57z1/
Here it's the resulting image: https://postimg.org/image/o4n3t6ic7/
As you can see, exists parts from the resulting image that remain white.
How i can resolve this?
You are flood-fill replacing the white pixels of your image but that won't work on pixels that are completely enclosed by non-white pixels (as in any paint program). Instead you can modify the definition of the colour white to make it transparent:
$image = imagecreatefrompng($second);
imagetruecolortopalette($image, false, 255);
$index = imagecolorclosest($image, 255, 255, 255); // find index of white.
imagecolorset($image, $index, 0, 0, 0, 127); // replace white with transparent black.
header('Content-Type: image/png');
imagepng($image);

GIF transparent background turned to black

I have a script that resizes uploaded images. It works fine for PNGs and JPGs but with GIFs it renders the transparency in the resized GIF black.
$src = imagecreatefromgif($file);
$dst = imagecreatetruecolor($newWidth, $newHeight);
imagecopyresampled($dst, $src, 0, 0, 0, 0, $newWidth, $newHeight, $width, $height);
imagegif($dst, $file);
From the manual page http://us3.php.net/manual/en/function.imagecopyresampled.php#104028
imagecolortransparent($new, imagecolorallocatealpha($new, 0, 0, 0, 127));
imagealphablending($new, false);
imagesavealpha($new, true);
is used by one poster to preserve transparency.
Here's a tip... Always check out user comments on php.net as they are generally very helpful in understanding the nuances of a function and providing tips for handling common tasks.
I'm assuming this goes to a web-page, which if it does you could just output the image tag with the correct attributes?
echo "<img src='$file' width='$newWidth' height='$newHeight' />";
You still have to set the transparency in the new image. The following is taken from the php docs:
<?php
// Create a 55x30 image
$im = imagecreatetruecolor(55, 30);
$red = imagecolorallocate($im, 255, 0, 0);
$black = imagecolorallocate($im, 0, 0, 0);
// Make the background transparent
imagecolortransparent($im, $black);
// ^^ This is the command you are missing.
// Draw a red rectangle
imagefilledrectangle($im, 4, 4, 50, 25, $red);
// Save the image
imagepng($im, './imagecolortransparent.png');
imagedestroy($im);
?>
In your case, you want to make the transparency the same color as the original transaprency - which I always made a hideous purple or something that would a) stick out like a sore thumb in my image manipulation software and secondly, have a RGB key that was almost impossible to have included in an image by mistake.

Image transparency not preserved when merging two images in PHP

When using examples from other posts to try and merge one PNG that has transparent parts on it with another non-transparent PNG, the foreground PNGs transparency is lost and defaults to white.
The code so far:
$width = 349;
$height = 250;
$base_image = imagecreatefrompng($_GET['bg']);
$top_image = imagecreatefrompng($_GET['fg']);
$merged_image = "merged.png";
imagesavealpha($top_image, true);
imagealphablending($top_image, true);
imagecopy($base_image, $top_image, 0, 0, 0, 0, $width, $height);
imagepng($base_image, $merged_image);
Can anyone suggest where I may be going wrong?
Coming out like this
Should look like this
Copy from Can PNG image transparency be preserved when using PHP's GDlib imagecopyresampled?
Codes should be like this:
imagesavealpha($base_image, true);
imagealphablending($base_image, false);
$image = imagecreatefrompng($_GET['bg']);
$frame = imagecreatefrompng($_GET['fg']);
imagealphablending($frame,true);
imagecopymerge($image, $frame, 0, 0, 0, 0, 0, 100, 100);
# Save the image to a file
imagepng($image, 'file-xyz.png');

Is attaining real transparency with imagettftext and imagecolortransparent possible?

When using imagettftext with an image rendered transparent via imagecolortransparent, the border of the text seems to have blended with the original background color (black) instead of the transparency, thus creating an outline of the text as seen here:
http://i.stack.imgur.com/xLSkK.png as opposed to using imagestring, here:
http://i.imgur.com/5R0gT.png
Now I'm not sure if there's a better way to combine images so they're created transparent from the start, or if there's some other transparency method I'm not aware of. Here's the relevant PHP code I'm using:
if ($type) {
$icon = imagecreatefrompng("images/" . $type . ".png");
}
else {
die('Invalid type. Valid types are: arcane, elysian, divine, spectral');
}
$img = imagecreatetruecolor(128, 25);
$black = imagecolorallocate($img, 0, 0, 0);
imagecolortransparent($img, $black);
imagecopymerge($img,$icon,0,0,0,0,28,25,100);
imagettftext( $img, 16, 0, 30, 20, $col, $font, $input_num );
header( "Content-type: image/png" );
imagepng( $img );
imagecolortransparent will never work very well because of anti-aliasing---the background color near outlines are not true black. Your best bet will be to use PNG images with transparent areas in the first place instead of ones with the black background..

Background transperancy in imagerotate()

Since last 2 days, I was trying to add transperancy to the background after rotating an image using imagerotate() PHP-GD function.
But, to my great disappointment, it's not working at all.
It's just giving out a black background behind it.
Here's my code -
$patchImageS = 'image.png'; // the image to be patched over the final bg
$patchImage = imagecreatefrompng($patchImageS); // resource of image to be patched
$patchImage = imagerotate($patchImage, 23, 0, 0);
imagepng($patchImage,'tt.png');
I tried to change the parameters being passed in function to
imagerotate($patchImage, 23, 5, 0);
imagerotate($patchImage, 23, 0, 5);
Any help would be highly appreciated.
After a number of 99% finished answers, here's the solution I've found:
// Create, or create from image, a PNG canvas
$png = imagecreatetruecolor($width, $height);
// Preserve transparency
imagesavealpha($png , true);
$pngTransparency = imagecolorallocatealpha($png , 0, 0, 0, 127);
imagefill($png , 0, 0, $pngTransparency);
// Rotate the canvas including the required transparent "color"
$png = imagerotate($png, $rotationAmount, $pngTransparency);
// Set your appropriate header
header('Content-Type: image/png');
// Render canvas to the browser
imagepng($png);
// Clean up
imagedestroy($png);
The key here is to include your imagecolorallocatealpha() in your imagerotate() call...
look for imagesavealpha() in the php-documentation - i think this is what you are looking for.
EDIT: here's an example:
$png = imagecreatefrompng('./alphachannel_example.png');
// Do required operations
$png = imagerotate($png, 23, 0, 0);
// Turn off alpha blending and set alpha flag
imagealphablending($png, false);
imagesavealpha($png, true);
// Output image to browser
header('Content-Type: image/png');
imagepng($png);
imagedestroy($png);
For anyone having problems with imagecopyresampled or imagerotate with black bars on background, I have found a code example here:
https://qna.habr.com/q/646622#answer_1417035
// get image sizes (X,Y)
$wx = imagesx($imageW);
$wy = imagesy($imageW);
// create a new image from the sizes on transparent canvas
$new = imagecreatetruecolor($wx, $wy);
$transparent = imagecolorallocatealpha($new, 0, 0, 0, 127);
$rotate = imagerotate($imageW, 280, $transparent);
imagealphablending($rotate, true);
imagesavealpha($rotate, true);
// get the newest image X and Y
$ix = imagesx($rotate);
$iy = imagesy($rotate);
//copy the image to the canvas
imagecopyresampled($destImg, $rotate, 940, 2050, 0, 0, $ix, $iy, $ix, $iy);

Categories