'Having aliasing edges when using Imagick in php to convert PDF to PNG

When I am converting PDF to PNG, I got a aliasing edges around the image (which is anti-aliasing in PDF).

PDF: no aliasing edge

PNG from Imagick: aliasing edge

This is my code:

$im = new Imagick();
$im->setResolution( 250, 250 );
$im->setBackgroundColor(new ImagickPixel('white'));
$im->readImage('pdf.pdf[0]');
$im->setImageAlphaChannel(Imagick::ALPHACHANNEL_REMOVE );
$im->setImageBackgroundColor('white');
$im->mergeImageLayers(Imagick::LAYERMETHOD_FLATTEN);
$im->setImageUnits(imagick::RESOLUTION_PIXELSPERINCH);
$im->setImageCompressionQuality(100);
$im->setimageformat('png');
header("Content-type: image/png");
echo $im;

I have tried mergeImageLayers, increasing Resolution, set White Background under it, and increase quality. However, no changes happened. You can download my pdf sample with this link: https://www.dropbox.com/s/ljm64vtcdxgwqnt/pdf.pdf?dl=0



Solution 1:[1]

The resolution of a PDF is arbritrary we could say each inch represents a kilometre and if our Units of Resolution are millimetres we could plot every 1 m square on a map, however for a sheet of printing paper that would be too crude so we use a finer convenient resolution of say 72000 mils per inch and declare that as 72 printers points per inch.

When we place vectors that have no thickness it makes for a well defined edge with no noticeable problems, until we need to convert them to pixels for imagery.

So ideally an image at 1000 dpi would be nice since any aliasing of vector edges would be hardly noticeable when zoomed out by 1000 to show that inch at 100 percent.

However the storage requirement would be horrific for coloured graphics as each square inch could, for highest fidelity, require up to 64 Mb of data storage. Thus we look for ways to minimise that by dropping bits per colour or reducing pixels per inch. In some cases one can make much more of an effect that the other but if both are optimised its even better. enter image description here

Here zoom into the original we can see how the high resolution source image is anti-aliased compared to the vector edge of the font.

For graphics a PNG at 256 colours rather than 16.7 million may not look very different if we are not worried about photographs. Likewise for thermal printing 2 colours would do. However that introduces more noticeable aliasing when sloping vectors are translated as the colour steps are more noticeable at lower resolutions such as 72 dpi.

So for the pdf in hand what might be an optimal compromise for this image @ a reasonable 600 dpi. However as a PDF that would become at least 128 KB bytes

enter image description here

If we drop resolution to 300 the letters will be less smooth when zoomed in and the rounded edges would also be degraded but we can hold the colours down to 256 to compensate and get a relative storage requirement of 25% enter image description here

There is no way to avoid aliasing of vectors into pixels but we can use coloured anti-aliasing to our advantage if we work in conjunction with pixel resolution.

Stored in a PDF with the extra info that 300 dpi image is 16,330 bytes and as a full page PDF it becomes 41,961 bytes thus much smaller storage than the source pdf.pdf which was 72,626 bytes and appearance is not much worse

The php example is 1128 colours @ 150 dpi thus should be worse enter image description here

And as pdf to image 125 colours @ 200 dpi is scale-wise 33% better than 150 enter image description here

It is finding the sweet balance in each case between colours and resolution that reflects apparent visual quality, there is no imagemagic it is test and adjust that gets closer to a human acceptable compromise, on a case by case basis. The PDF is not the factor other than it holds vector objects like text or SVG it is the conversion of mixed scale images enblock that distorts their output.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1