imagecreatefrompng() transparent part of png is black - php

I am creating a poster using PHP and I want to add figures on the poster.
I use the following code to add them:
$src1 = imagecreatefrompng("m2.png");
$widthsrc=0;
$heightsrc=0;
list($widthsrc, $heightsrc, $typesrc, $attrsrc) = getimagesize("m2.png");
$background = imagecolorallocate($src1, 0, 0, 0);
imagecolortransparent($src1, $background);
imagealphablending($src1, false);
imagesavealpha($src1, true);
imagecopyresampled($my_img,$src1,$line2X1+100*$resize,$line2Y1,0,0,1000*$resize,1000*$resize,$widthsrc,$heightsrc);
The problem is that the places that the figures should be transparent, they are black.
I have already looked at the following posts:
imagecreatefrompng-makes-a-black-background-instead-of-transparent
hp-resizing-png-images-generate-black-background
png-has-black-background
But I haven't been able to create a solution that works for me.

Well that was easy XD Converting comment to answer:
Your mistake was in defining the background colour. You should use this:
$background = imagecolorallocatealpha($src,0,0,0,127);
However, it is probably a good idea to be safe, and avoid using a "transparent" colour that already exists on your image. The "traditional" transparent colour from old sprite-based games is magenta, since it is very unlikely that you'll have straight magenta on your image!
$background = imagecolorallocatealpha($src,255,0,255,127);

Related

Convert all pixels of a given color to transparent in iMagick (PHP) syntax?

I want to convert a given color to transparency with iMagick. I have found one way to do this, but it behaves like a paint bucket rather than examining the entire image.
For the following example, I'm using this:
$transparentColor = new ImagickPixel('transparent');
$image->floodFillPaintImage($transparentColor, 20000, "#0009c5", 0, 0, false, Imagick::CHANNEL_ALPHA);
This is the input image
This is the output image
The result I'd like to see is all the blue areas turned to transparency. Unfortunately, it seems that "fill" is the key point in this function and hence stops when confronted with non-"target" colors.
Does anyone know how to accomplish turning all the blue areas to transparent using iMagick (not command line imageMagick)?
Thanks in advance!
Try:
$image->transparentPaintImage($targetColor, $alphaLevel, $fuzz, false);
If the transparent areas are "messy", it may help to despeckle:
$image->despeckleimage();
Doc: http://php.net/manual/en/imagick.transparentpaintimage.php

ImageMagick / Imagick: Convert a PNG with Alpha channel into a 2 color image (Color, Transparent)

I would like to know and find out, how I can colorize/replace any pixel of an image, that is not (fully) transparent with an opaque pixel.
For example, having a multicolored Logo with transparent pixels, I would like to convert it in to a logo with only the color #ff0000, and not change the transparent background.
I want to achieve this with the PHP Imagick Library. I cannot find any good documentation.
I thought that Imagick::thresholdImage would be a helper, but there is no documentation about the threshold parameter.
Best results are achieved with this fragment of code. But still not working perfectly. Some pixels - i guess those with alpha > 0 and < 1 are not replaced.
$image = new \Imagick($source);
$image->setImageFormat('png');
$fill = new \ImagickPixel('#ff0000');
$image->thresholdImage(0);
$image->paintOpaqueImage('#ffffff', $fill, 1);
$image->writeImage($destination);
I would like to know and find out, how I can colorize/replace any pixel of an image, that is not (fully) transparent with an opaque pixel.
You almost certainly don't.
The code below does what you are asking (I think) and the output looks terrible. Perhaps you should give an example input image, and a hoped for example output image, that you have edited in Photoshop, to show what you were hoping for.
Input image:
Output image:
$imagick = new Imagick("fnord.png");
// Get the alpha channel of the original image.
$imagick->separateImageChannel(\Imagick::CHANNEL_ALPHA);
// Make all the colors above this pure white.
$imagick->whiteThresholdImage("rgb(254, 254, 254)");
// Make all the colors below this pure black.
$imagick->blackThresholdImage("rgb(254, 254, 254)");
// We want the mask the other way round
$imagick->negateImage(false);
$imagickCanvas = new \Imagick();
$imagickCanvas->newPseudoImage(
$imagick->getImageWidth(),
$imagick->getImageHeight(),
"xc:rgb(255, 0, 0)"
);
// Copy the mask back as the alpha channel.
$imagickCanvas->compositeImage($imagick, \Imagick::COMPOSITE_COPYOPACITY, 0, 0);
// Write out the image.
$imagickCanvas->setImageFormat('png');
$imagickCanvas->writeImage("./output.png");

php image filter "colorize" destroys image details

i am trying to to colorize a black and white picture on my server.
i have tried doing this with multiple methods and the only one that kind-of-works is gd imagefilter via filter IMG_FILTER_COLORIZE.
it does kind of colorize the image in exactly the same color that i want, but it loses all the details on the image, as if it just trimmed black dots that were not black enough and thinned all the black lines, making them almost invisible. here is what i'm talking about:
this result was achieved with this code
$im=imagecreatefromjpeg($orig_file);
imagefilter($im, IMG_FILTER_COLORIZE, 71, 92, 10);
imagejpeg($im, $output_file, 95);
why is this happening? are there any other methods how i could colorize the image? my original image is quite large and i can't iterate over it as it is too slow; that's why i'm trying to use a library that would do this
i have managed to achieve the desired result with help of Imagick and compositeImage. here is the result
how i achieved it is kind of a trick that works only in a very specific condition- which is the need to have the background white and only black/gray objects in front (or the exact opposite). this technique wouldn't work on a background with transparency
the idea is to have 2 layers- underneath is the layer with original grayscale image and the top layer- fully filled with the desired color. then you composite these images using "COMPOSITE_LIGHTEN" (you might use other methods, like darken for example- if you have white objects on a black background)
this is the code
$base_color="#475c0a";
$im=new Imagick($orig_file);
$im2 = new Imagick();
$im2->newImage($im->getImageWidth(), $im->getImageHeight(), new ImagickPixel($base_color) );
$im->compositeImage($im2, Imagick::COMPOSITE_LIGHTEN, 0, 0);
$im->writeImage($new_image_path);
hope this will help someone out

How to anti-alias an image with PHP? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Remove white background from an image and make it transparent
I currently have a code that removes the white background from an image, it looks like this:
function transparent_background($filename, $color)
{
$img = imagecreatefrompng($_SERVER['DOCUMENT_ROOT'].'/'.$filename);
$colors = explode(',', $color);
$remove = imagecolorallocate($img, $colors[0], $colors[1], $colors[2]);
imagecolortransparent($img, $remove);
imagepng($img, $_SERVER['DOCUMENT_ROOT'].'/'.$filename);
}
transparent_background('test.png', '255,255,255');
However, once it exports, the edge is very rough. This is what it looks like (note that this is just part of my image):
http://img211.imageshack.us/img211/97/2125c773e32c432b91e1127.png
I added a black background behind that image to show the edge better. So is there a way that I can add a line to the function or edit the function so the edges are smoother/anti-aliased? Thanks!
There is no easy way to do this. The edge of the original image was anti-aliased to the white background. When you remove the pure white, you're left with a lot of pixels near the edge that are close to white. When you see those pixels against a dark color, they're going to stand out and look "rough". You won't get a smooth edge against a transparent background if it's not in the source image.
The final result of the output is being determined by the initial image quality of the image you are importing. PHP can only anti-alias elements that are drawn on an image.
One solution, a total sledgehammer approach, would be to resample the image up, and then down again. Your results will vary depending on the image in question, and it will almost always be not good.
The best solution for your particular problem is to use better quality imported images in the first place.

PHP Image manipulation moire effect

I am making a site where people can upload their own background images. One of the things users really having a problem understanding is image sizes and resolution. If I say 'Make sure your background is at least 1080x1920 pixels (Full HiDef)' I am guessing a good 70% of people will not know what this means or how to do it.
So what I would like to do is enlarge small images in a nicer way than just making them blurry. What I would like to do is something like this:-
http://nanotux.com/plugins/fullscreenr/index.html
where basically every other dot is a black pixel, that way small images will be twice the size when they are stretched to 1080x1920 and generally look better.
Does anyone know of a way to do this with PHP's image functions?
(as an aside does anyone know what this type of effect should be called? Moire? would that be accurate?)
Thanks in advance
If I understood you well, you want to set every second pixel in x and y dimensions to black on the stretched image?
This should do the trick (not tested, I relied on PHP documentation).
$initialImage = ... // handle to the image
$srcWidth = imagesx($initialImage);
$srcHeight = imagesy($initialImage);
$maxX = 1920;
$maxY = 1080;
$newImage = imagecreatetruecolor($max_x, $max_y);
imagecopyresampled ($newImage, $initialImage, 0,0,0,0, $maxX, $maxY, $srcWidth, $srcHeight);
$BLACK = imagecolorallocate($newImage, 0, 0, 0);
for($x=0; $x+=2; $x<$max_x){
for($y=0; $y+=2; $y<$max_y){
imagesetpixel($newImage, $x, $y, $BLACK);
}
}
Documentation: imagesetpixel, imagecolorallocate, imagecopyresampled,
imagecreatetruecolor.
Read PHP documentation and examples there. Remember to use imagecopyresampled instead of imagecopyresized to have better quality.
The most optimal way would be to create a transparent raster (.png) "by hand" (i.e. create it programmatically as in jakub.gieryluk's solution), and overlay that, multiple times if needed, via imagecopy().
Drawing pixel by pixel is painfully slow.

Categories