Grayscale PHP imagefilter issues - php

I'm having issues incorporating imagefilter in the following. Output is a color image. I've tried a few different options, based on php.net documentation but I either get a black image or a color image, not grayscale.
$data = file_get_contents($_FILES['image']['tmp_name']);
$vImg = imagecreatefromstring($data);
$dstImg = imagecreatetruecolor($nw, $nh);
imagefilter($dstImg, IMG_FILTER_GRAYSCALE); // imagefilter added
imagecopyresampled($dstImg, $vImg, 0, 0, $x1, $y1, $nw, $nh, $w, $h);
imagejpeg($dstImg, $path);
imagedestroy($dstImg);
I know my usage is complete wrong, so any help would be much appreciated!

you need to make the source grayscale.
replace
imagefilter($dstImg, IMG_FILTER_GRAYSCALE);
with
imagefilter($vImg, IMG_FILTER_GRAYSCALE);

Related

Fill png transparency with background color

I'm refactoring an old image crop/resize library i wrote about 5 years ago and i'm stuck trying to restore one of it's functionalities. The funny part is that i'm not even sure it worked back then since i probably never actually used it.
I need to be able to work on png images while keeping transparency (which works), but i also wan't to be able to fill the transparent part of the image with a color.
Creating a blank image and filling it with a color works fine, but when i try to paste my png over it, the background is transparent again.
Here's a simplified version of my code:
<?php
$src = imagecreatefrompng($pathToSomePngFile);
imagealphablending($src, false);
imagesavealpha($src, true);
$output = imagecreatetruecolor($width, $height);
if ($backgroundColor) {
$fillColor = imagecolorallocate(
$output,
$backgroundColor['r'],
$backgroundColor['g'],
$backgroundColor['b']
);
imagefilledrectangle(
$output,
0,
0,
$width,
$height,
$fillColor
);
} else {
imagealphablending($output, false);
imagesavealpha($output, true);
}
imagecopyresampled(
$output,
$src,
0,
0,
0,
0,
$width,
$height,
$width,
$height
);
imagepng($output, $pathToWhereImageIsSaved);
UPDATE
Updated with delboy1978uk's solution to get it to work without changing my other settings.
Something like this should work.
<?php
// open original image
$img = imagecreatefrompng($originalTransparentImage);
$width = imagesx($img);
$height = imagesy($img);
// make a plain background with the dimensions
$background = imagecreatetruecolor($width, $height);
$color = imagecolorallocate($background, 127, 127, 127); // grey background
imagefill($background, 0, 0, $color);
// place image on top of background
imagecopy($background, $img, 0, 0, 0, 0, $width, $height);
//save as png
imagepng($background, '/path/to/new.png', 0);

Invert color and preserve transparency with PHP

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

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.

PHP+GD: imagecopymerge not retaining PNG transparencies

I have two PNG files, "red.png" and "blue.png"; they are both mostly transparent, but there is a few pixels of red or blue splotches in various places.
I want to make a PHP script that merges the two; it should be as simple as something like:
$original = getPNG('red.png');
$overlay = getPNG('blue.png');
imagecopymerge($original, $overlay, 0,0, 0,0, imagesx($original), imagesy($original), 100);
header('Content-Type: image/png');
imagepng($original);
When I run this script, all I get is the blue dots -- with the transparency lost. I saw that I should add these:
imagealphablending($original, false);
imagesavealpha($original, true);
(on both the original and the overlay?) And that doesn't seem to help any.
I saw a few workarounds on PHP.net, something to the tune of:
$throwAway = imagecreatefrompng($filename);
imagealphablending($throwAway, false);
imagesavealpha($throwAway, true);
$dstImage = imagecreatetruecolor(imagesx($throwAway), imagesy($throwAway));
imagecopyresampled($dstImage, $throwAway,0,0,0,0, imagesx($throwAway), imagesy($throwAway), imagesx($throwAway), imagesy($throwAway));
, which should convert the PNG to a "truecolor" image and retain transparency. It does seem to do so, but now all I see is blue on a black background.
What do I do?!
This works perfectly for me:
$img1 = imagecreatefrompng('red.png');
$img2 = imagecreatefrompng('blue.png');
$x1 = imagesx($img1);
$y1 = imagesy($img1);
$x2 = imagesx($img2);
$y2 = imagesy($img2);
imagecopyresampled(
$img1, $img2,
0, 0, 0, 0,
$x1, $y1,
$x2, $y2);
imagepng($img1, 'merged.png', 0);
PHP Version 5.3.2
GD Version 2.0
libPNG Version 1.2.42
Have you tried saving the image to a file and checking that?

PNG Transparency with PHP

Hey having some trouble trying to maintain transparency on a png when i create a thumbnail from it, anyone any experience with this? any help would be great, here's what i am currently doing:
$fileName= "../js/ajaxupload/tees/".$fileName;
list($width, $height) = getimagesize($fileName);
$newwidth = 257;
$newheight = 197;
$thumb = imagecreatetruecolor($newwidth, $newheight);
imagealphablending($thumb, true);
$source = imagecreatefrompng($fileName);
imagealphablending($source, true);
imagecopyresized($thumb, $source, 0, 0, 0, 0, $newwidth, $newheight, $width, $height);
imagesavealpha($thumb, true);
imagepng($thumb,$newFilename);
I have had success doing it like this in the past:
$thumb = imagecreatetruecolor($newwidth, $newheight);
imagealphablending($thumb, false);
imagesavealpha($thumb, true);
$source = imagecreatefrompng($fileName);
imagealphablending($source, true);
imagecopyresampled($thumb, $source, 0, 0, 0, 0, $newwidth, $newheight, $width, $height);
imagepng($thumb,$newFilename);
I found the output image quality much better using imagecopyresampled() than imagecopyresized()
Forget the color transparency index, it never works in all rendering products. Instead use an alpha layer mask:
$image = imagecreatetruecolor($size, $size);
imagealphablending($image, false);
imagesavealpha($image, true);
$trans_layer_overlay = imagecolorallocatealpha($image, 220, 220, 220, 127);
imagefill($image, 0, 0, $trans_layer_overlay);
Those functions access the underlying gdlib library, which is a fine toy, but not something that makes for nice results. If you have the option, use imagemagick instead. The downside is that there are currently no good php-bindings, so you need to access it over the shell, which you're usually not allowed on shared hosts.
See dycey's answer to "How do I resize...". Essentially, you need to fill the entire background with transparency before you do any other operations.
imagecopyresized does not support transparency properly.
imagecopymerge does, but it doesn't resize.
The solution? You'd probably end up resizing the thing manually.

Categories