php imagick annotation antialiasing - php

I have a webcam and want to add some annotations to image, but antialiasing works strange. I'll try to explain:
I have an image like this:
Then I add semi-transparent rectangle and put text over it:
// add background black rectangle
$draw->setFillColor('black');
$draw->setFillOpacity(0.5);
$draw->rectangle( 0, 10, $cam['width'], 70 ); // Draw the rectangle
// add lead text
$draw->setFont('ARIALBD.TTF');
$draw->setFontSize(14);
$draw->setFillColor('white');
$draw->annotation(20, 35, $cam['text']);
// add timestamp
$draw->setFont('ARIAL.TTF');
$draw->setFontSize(12);
$draw->setFillColor(new ImagickPixel('#f3ac01'));
$draw->annotation(20, 50, date("Y-m-d H:i:s"));
$img->drawImage($draw);
And get something like this:
Huh, but timestamp looks ulgy(look at minutes/seconds). Trying to disable antialiasing:
$draw->setTextAntialias(false);
and now it looks still ugly(look at hours), but now it has sharp edges:
How can I get result with smart antialiasing, like this(I know PS uses own antialiasing, but IMagickDraw deal real bad result):

For me it looks more like the compression level of the whole image when saved than the antialiasing, have a look at setCompressionQuality, and tweak the compression quality until you avoid the "blurriness" you have in the picture.

Try the different font first. Here is example of open sans (another link) font.

Related

PHP: How do I change a color in an 8 bit PNG (png has transparency) using GD Library

I have an 8 bit PNG (original is here: https://i.ibb.co/s3024Y8/1000x1500-autumn-leaves.png) and I want to change the colour of the leaves.
I have a list of the hex colours that need to be changed and a list of the colours they need to be changed to - all to be done dynamically. I'm working towards a solution that has to work off those lists - but that can wait. For this question, being able to change the colour of just one leaf will do.
After changing the colour of the leaf I need the image to retain its transparent areas (so I can lay it on top of another image - that part I can do).
I am quite new to the GD library and am getting confused. I understand that an 8-bit PNG (as created in Photoshop) has full alpha - and that needs to be preserved.
That leads me to the start of my code:
$im = ImageCreateFromPNG('https://i.ibb.co/s3024Y8/1000x1500-autumn-leaves.png');
ImageAlphaBlending($im, false);
imagesavealpha($im, true);
Everything I've tried after that fails miserably. By that, I mean that the colour doesn't change. No error message, just no change in colour. It seems that the following has no effect when using that image:
$myColourToChange = imagecolorallocatealpha($im, 100, 24, 11, 0); // colour of dark brown leaf
imagecolorset($im, $myColourToChange, 255, 0, 0, 0); // try changing it to red, fully opaque
I've even tried (which gives 6559755)
$myColourToChange = imagecolorresolvealpha($im, 100, 24, 11, 0);
I think things are failing (ie the colour doesn't change) because the image I'm using isn't a paletted image in the way that GD needs it to be, in order for me to use imagecolorset
I've tried converting it to one using imagetruecolortopalette but that gives unpredictable results on the image, with all sorts of artifacts not visibly present in the original image - and the colour values change slightly.
Note that the following are representations if you want to experiment, use the image link above.
Original image before imagetruecolortopalette - dark brown leaf colour: #64180B
After imagetruecolortopalette - dark brown leaf colour: #631A0C
So how do I specify the colour that needs to be changed and then change it to the given colour? If it means I must use imagetruecolortopalette how do I deal with the artifacts and the colour change I get when using it?
(I won't know in advance the location of colours that need changing, so imagecolorat won't help)
Thanks in advance :)

change color range image

I am using PHP-Imagick to convert a PDF into images, which works fine.
A simplified example:
$im = new imagick();
$im->setResolution(250,250);
$page = $pdfPath."[0]";
$im->readImage($page);
if($im->getImageColorspace() == Imagick::COLORSPACE_CMYK)
{
$im->transformImageColorspace(Imagick::COLORSPACE_SRGB);
$im->autoLevelImage();
}
$im->setImageFormat('jpg');
$im->setImageCompression(imagick::COMPRESSION_JPEG);
$im->setImageCompressionQuality(90);
$im->writeImage("page1.jpg");
However the coloring seems to differ from the original PDF, for example (see image)
left side is original PDF.
right side the rendered image, which has different colors than the original.
It seems that the original color of dark-pink turns into purle. Also red colors seem to saturate.
I have tried the following, but none worked:
reduce saturation (e.g. $im->modulateImage(100, 80, 100); ) But this causes red to become orange and yellow colors to turn greenish.(see example below)
playing around with image filter (e.g. imagefilter($im, IMG_FILTER_COLORIZE,100, 0, 0); ), but this also changes all colors.
Thinking it had to do with differences between CMYK and RGB, I have added $im->transformImageColorspace() doesn't do anything to fix this.
playing with various hue filters, but these change all colors of the image also.
Question: it seems I need to reduce the redness of the image? (I think it's the excessive red color causing the difference) without affecting the other colors, so that for example yellow remains yellow. Is there a way to do this in PHP?
The solution is to add the following line before reading the image:
The code should be:
$im->setColorspace(Imagick::COLORSPACE_SRGB);
$im->readImage($page);

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

Weird shadow/blur when drawing a single-pixel line with ImagickDraw

So I'm trying to draw a line with Imagick today. Sounds simple enough right?
Here's the code I have:
$image = new Imagick();
$image->newImage(100, 100, 'white');
$image->setImageFormat('png');
$line_color = new ImagickPixel('#555555');
$line_weight = 1;
$line = new ImagickDraw();
$line->setResolution(100, 100);
$line->setStrokeWidth($line_weight);
$line->setStrokeColor($line_color);
$line->line(20, 20, 20, 60);
$image->drawImage($line);
$image->writeImage('test.png');
Nothing surprising, I create a 100x100 white image, I set a line color at 555555, a line weight at 1, I create my ImagickDraw object and tell him to draw a line.
The problem is that the output looks like this: http://i.stack.imgur.com/hM8QS.png
Which looks fine at first, until you zoom in and see this: http://i.stack.imgur.com/O6Yie.png
I tried several settings for the color, the weight and the resolution, but I can't get rid of this weird shadow/blur effect. It does this with pretty much anything I draw (lines, rectangle etc...) except with points. So if I want I can create my single-pixel line with a series of points and a simple for loop, but it will really get tedious to do. Especially since I'm not gonna draw just this single line.
So, anyone has any idea of what is happening? How can I get rid of this behavior?
The effect you are seeing is due to stroke anti-aliasing being enabled. You can disable it with setStrokeAntialias.
$line->setResolution(100, 100);
$line->setStrokeWidth($line_weight);
$line->setStrokeColor($line_color);
$line->setStrokeAntialias(false);
Reenable stroke anti-aliasing whilst drawing curved lines to avoid aliasing artifacts.
Bizarely, in my tests, this causes the line to disappear completely when the stroke color is set to #555555 (or an equivalent representation) as it is in your code sample. However, setting the color to #545454 or #565656 causes the line to be drawn correctly, without the shadow/blur effect you described.

Categories