Image Conscious: Why your PNG images look terrible

Terrible from a technical point of view ... bad photos or artwork have no fix

pixelated mouth
Credit: Steven Straiton / Flickr

A friend of mine asked me a question that may have puzzled many of you: "Why are the images in my blog post kind of crappy looking?" (I should make it clear that the question concerns his blog, not mine ...)

In my friend’s case he taken screen shots in PNG [pronounced “ping”] format and the CMS he was working with had automatically resized them to be larger by a factor of roughly 2.5 and they looked blurred. My friend initially blamed the image format for the fuzziness but PNG was not the culprit.

PNG, which stands for Portable Network Graphics, is “a raster graphics file format that supports lossless data compression” and is the successor to GIF format without the intellectual property baggage that GIF comes with [thanks to Unisys]. Like GIF, PNG supports transparency but unlike GIF doesn’t support animation. It is also:

… the most used lossless image compression format on the Internet.

PNG supports palette-based images [with palettes of 24-bit RGB or 32-bit RGBA colors], grayscale images [with or without alpha channel], and full-color non-palette-based RGB[A] images [with or without alpha channel]. PNG was designed for transferring images on the Internet, not for professional-quality print graphics, and therefore does not support non-RGB color spaces such as CMYK.

Crucially, PNG is a raster-based rather than vector-based format so it describes the attributes of a sequence of pixels rather than a series of connected points and filled areas. Unlike a vector formats that can be accurately scaled to be larger or smaller, raster formats have problems scaling. For example, in a vector format the points [100,200] and [200,300] connected by a blue line 10 pixels wide can be scaled by any factor you like. So for, say, enlargement by 2.5 would set the new, scaled points at [250,500] and [500,750] connected by a blue line 25 pixels wide.

screen shot 2015 03 25 at 7.24.01 pm Mark Gibbs

Upscaling a vector image

Raster images are different because we know nothing about shapes, we simply know that the two adjacent pixels at, say, [100,200] and [101,200] are red and yellow respectively. Our problems start when we try to upscale the image.

For very large upscaling factors the image becomes extremely “blocky” and obviously not very useful. On the other hand at low upscaling factors we’ll have problems with colors and various types of distortion depending on how we handle the pixel data.

pixelated apples Clyde Robinson / Flickr

But consider applying a scaling factor of +2.5 to the pixel [100,200]. In the new, larger image the pixel is at [250,500] and it's also bigger; moreover, it’s no longer 1 pixel by 1 pixel, it’s now 2.5 by 2.5 pixels, extending from 250 to 252.5 on the X axis and from 500 to 502.5 on the Y axis. As there’s no such thing as a half pixel we have to decide where to locate the fractional parts of the upscaled pixel.

screen shot 2015 03 25 at 8.50.28 pm Mark Gibbs

Upscaling a raster image

So, focusing on the X axis, do we allocate the whole of pixel 252 to the upscaled pixel? And there’s the problem of the next pixel that was at [101,200] which should now start at [252.5,500] on the X axis. There’s a number of things we could do such as allocate all half pixels to the right (making our first upscaled pixel 3 pixels wide and the next upscaled pixel only two pixels wide) but the final image will be distorted with lines and edges becoming thinner or jagged.

A simple solution is to blend the colors of the two upscaled pixels to create the color (in this case, orange) of the pixel they share, namely[252,500]. The downside is that the final upscaled image will look “fuzzy” and out of focus. Note that we also have to average out all of the other "half" pixel regions around an upscaled pixel; in the case of the above example it's all of the "mix" regions".

As you might imagine, there are a number of algorithms for doing this kind of “tweening” but no matter which algorithm you choose, the end result will be a degraded final image. The process of enlarging by a non-integer value results in data loss, blockiness, and blur while integer values just introduce blockiness. Yes, there are algorithms that aim to "smooth" the blockiness but they don't always work and, at best, approximate the original image.  

Downscaling raster images generally delivers better results than upscaling but, as with upscaling, there’s no getting away from introducing artifacts, de-sharpening, and color changes. In reality downscaling large raster images is usually not too bad and most image handling software such as Photoshop and Krita will do so very nicely but even the best software will have trouble upscaling.

So, in general, aim for images that are much bigger than the size you need and shrink them to fit the target space. 

Questions? Comments? Fire away below ...

Join the Network World communities on Facebook and LinkedIn to comment on topics that are top of mind.
Must read: 10 new UI features coming to Windows 10