Artifacts when scaling a PNG with semi-transparent pixels
Swiss army knife of image processing
Brought to you by:
bfriesen
In the simplest case, if you have a circle with antialiasing on a transparent background and scale it down with GraphicsMagick, a darker border will appear.
$ gm convert -size 90x90 xc:none -fill "#D3DEE6" -stroke none -draw "circle 45,45 45,0" +antialias circle.png
$ gm convert -scale 24 circle.png circle-24.png
circle.png:
circle-24.png
Try "-resize" instead of "-scale". BTW "+antialias" means do not use antialiasing.
That seems to work, thanks :)
Last edit: Jorge Bernal 2016-04-08
ScaleImage() suffers from two problems related to the blending of fully transparent pixels with non-fully transparent pixels during the scaling operation.
The first is that the colour values for fully transparent pixels are contributing to the colour values of the blended pixels when they should not.
The second is that the colour values of pixels blended with fully and non-fully transparent pixels are scaled as though the fully transparent pixels contribute to the blended pixels' colour values when they should not. For example, if blending 10% of a fully opaque white pixel with 90% of a fully transparent black pixel one would expect the blended pixel RGBA values to be 255,255,255,25.5 assuming 8 bit colour but they are in fact 25.5,25.5,25.5,25.5.
The provided patch solves the first issue by treating the colour values of fully transparent pixels as zero and the second issue by recording the volume of each blended pixel made up of pxiels that are not fully transparent (0.1 in the above example) and then scaling the blended pixel RGB values by dividing by that amount. In the above example, 25.5/0.1 = 255.
I find it easy to test this by scaling a white ellipse with transparent background and then compositing that onto a white background image:
It is worth patching ScaleImage() as it is considerably faster than ResizeImage() and also because we should always fix bugs ;-)
Troy Patteson
Last edit: Troy Patteson 2018-12-18
Thanks to Troy, this problem is finally solved. See Mercurial changesets 15870:113103cc7272 and 15871:e82340b7c814.