I'm trying to create a function that receives a PNG image and returns it with inverted colors. However, I'm having trouble with the transparency/alpha channel: basically, transparent pixels are coming back as either black or white, and thus transparency is not retained.
This is an example of a source image (which will of course vary), a PNG with a transparent background:
I would like to invert those colors while preserving transparency/alpha channel, like a CTRL+I in Photoshop. I'm using GD imagefilter function with the IMG_FILTER_NEGATE parameter
With the code:
$im = imagecreatefrompng($image_file);
imagefilter($im, IMG_FILTER_NEGATE);
header('image/png');
imagepng($im,NULL,0);
But it yields:
As you can see, transparent pixels turned black.
I then tried adding the alpha channel to the function imagecreatefrompng (like this):
$im = imagecreatefrompng($image_file);
imagealphablending($im, false);
imagesavealpha($im, true);
imagefilter($im, IMG_FILTER_NEGATE);
header('image/png');
imagepng($im,NULL,0);
But now I get white instead of black:
Now the issue seems to happen after the imagefilter function is applied. For example, if I run this code:
$im = imagecreatefrompng($image_file);
imagealphablending($im, false);
imagesavealpha($im, true);
//imagefilter($im, IMG_FILTER_NEGATE);
header('image/png');
imagepng($im,NULL,0);
The output image retains its transparent background, while remaining identical to the original image.
How can I invert colors of transparent PNGs without losing the transparent background?
NOTE: this is not the same question as imagecreatefrompng() Makes a black background instead of transparent? - the inversion step is the tricky part here
Here's what worked for me, dealing with transparent background and inverting image. Note that I'm using base64.
$im = imagecreatefromstring(base64_decode(str_replace('data:image/png;base64,', '', $base64)));
$width = imagesx($im);
$height = imagesy($im);
$dest_image = imagecreatetruecolor($width, $height);
imagealphablending($dest_image, FALSE);
imagesavealpha($dest_image, TRUE);
imagefilter($im, IMG_FILTER_NEGATE);
imagecopyresampled($dest_image, $im, 0, 0, 0, 0, $width, $height, $width, $height);
//optional output back to base64 or use imagepng with destination
ob_start();
imagepng($dest_image);
$contents = ob_get_contents();
ob_end_clean();
$base64 = 'data:image/png;base64,'.base64_encode($contents);
Related
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);
I have the following problem.
I have a PNG file (http://meteopage.com/beta/image.png), which is already partially transparent and I would like to make the "pink" border also transparent.
I have read some of the instructions here and came up with a code, which does replace the border with transparent point, but all the rest, which was already transparent, turns into black: http://meteopage.com/beta/radar2.php
My code looks like this:
<?php
$file="image.png";
$im = imagecreatefrompng($file);
imagealphablending($im, false);
$new = imagecolorclosest($im, 255, 0, 255);
imagecolortransparent($im, $new);
imagesavealpha($im, true);
header('Content-type: image/png');
imagepng($im);
?>
I tried adding those imagesavealpha and imagealphablending commands, but still no luck, it is black as you can see in the link Ive attached. Would anyone know how to maintain the original transparency and just "add" those pink pixels to it?
Your image is palette-based, not true colour, so the calls to imagealphablending() and imagesavealpha() aren't needed.
The simplest way to do this is to replace the pink colour in the palette-index with a transparent one, like so:
$file = 'image.png';
$im = imagecreatefrompng($file);
$new = imagecolorclosest($im, 255, 0, 255);
imagecolorset($im, $new, 255, 0, 255, 127);
header('Content-type: image/png');
imagepng($im);
Note that this requires PHP >= 5.4 otherwise imagecolorset() won't accept the alpha parameter.
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');
I am using PHP to rotate an PNG image, with a transparant background. But whatever I try, there are still some black lines around the original image.
How do I remove the black lines. Everything else works fine. The image is transparant, the image is rotated, the new corners are also transparant. Just the black lines around the original square (which is rotated) are annoying me.
I use this code:
$angle = -100;
header('Content-type: image/png');
$image = 'http://mapning.com/img/plane.png';
$file = imagecreatefrompng($image);
$rotate = imagerotate($file, $angle, 0);
imageSaveAlpha($rotate, true);
ImageAlphaBlending($rotate, false);
$transparentColor = imagecolorallocatealpha($rotate, 200, 200, 200, 127);
imagefill($rotate, 0, 0, $transparentColor);
imagepng($rotate);
I found my answer here:
http://ru2.php.net/manual/en/function.imagerotate.php#47985
I think better use imagick
Here is an extension for PHP
Or if you want with GD see here
http://ru2.php.net/manual/en/function.imagerotate.php#46338
I am trying to write text onto a png, however when I do it puts a dark border around it, I am not sure why.
The original image:
The processed image:
Code:
// Load the image
$im = imagecreatefrompng("admin/public/images/map/order/wally.png");
// If there's an error, gtfo
if(!$im) {
die("");
}
$textColor = imagecolorallocate($im, 68, 68, 68);
$width = imagesx($im);
$height = imagesy($im);
$fontSize = 5;
$text = "AC";
// Calculate the left position of the text
$leftTextPos = ($width - imagefontwidth($fontSize)*strlen($text)) / 2;
// Write the string
imagestring($im, $fontSize, $leftTextPos, $height-28, $text, $textColor);
// Output the image
header('Content-type: image/png');
imagepng($im);
imagedestroy($im);
I've had this issue several times, let me find the answer...
Ok, found something:
imagesavealpha($im, true);
imagealphablending($im, true);
Write that before imagepng.
Yes, saving with alpha is important but loading it is important as well. Your PNG image might have transparency but it is good practice to account for that as well.
You'd need to create true color image, set alpha color and then draw your loaded image with text over it. So something like this:
// create true color image
$img = imagecreatetruecolor($width, $height);
$transparent_color = imagecolorallocatealpha($img, 255, 255, 255, 0);
imagealphablending($img, false);
imagefillrectangle($img, 0, 0, $width, $height, $transparent_color);
imagealphablending($img, true);
// draw previously loaded PNG image
imagecopy($img, $loaded_img, 0, 0, 0, 0, $width, $height);
// draw your text
// save the whole thing
imagesavealpha($img, true);
imagepng($img, $file);