What is PNGQuant?
PNGQuant is a free to use, open source (available under a BSD-like license) command line utility and library for converting PNG files from 24/32-bit PNG images to 8-bit paletted PNG images.
This conversion has the effect of significantly reducing the file size (as much as 70%), which PNGQuant is capable of doing with little to no visual loss of quality. This is actually a lossy conversion, however PNGQuant employs several very clever algorithms that could make you believe otherwise.
You can find out more on their website, and the source code (written in C99) is available on GitHub.
What is an 8-bit Palette Image?
PNGQuant works by converting to 8-bit paletted images. What this means is that there is some sort of color palette – a list of colors stored within the PNG. An 8-bit palette image allows for 256 entries within the palette, which means up to 256 colors can be used in the image. Each entry consists of 3 or 4 channels, which specify red, green and blue values, with an optional alpha (transparency) channel. Each pixel within the image stores an 8-bit reference to a entry in the palette.
Here is a visual representation of that:
So what does PNGQuant convert from? The most common type of PNG images are 24-bit or 32-bit ‘True Color’ images. Again, they have 3 or 4 channels specifying red, green, blue, and optionally alpha, but they differ in how they specify pixel data. With True Color images, rather than referring to a palette of colors, each individual pixel specifies its own color in the form of an 8-bit value for each channel.
There are positives and negatives for each image type. So palette images can have 256 colors, whereas because each pixel in a True Color image specifies it’s own color, that allows for 16,777,216 possible colors to choose from on a 24-bit RGB image, and 4,294,967,296 different combinations on 32-bit RGBA images.
This is the reason why palette images typically have a much lower file size. True Color images require 3 or 4 bytes for RGB and RGBA images respectively. Whereas a palette image only requires 1 byte per pixel, with the addition of 256 3 or 4 byte values for the palette. This difference may seem insignificant, but it can very quickly add up, for example when you consider that in a 1920×1080 image you make that saving 2,073,600 times.
How Image Optimisation works?
But surely if you reduce an image down from 16,777,216 possible colors to 256 colors, you should expect a massive reduction in image quality? This is where PNGQuant really excels over other lossy PNG optimizers. I won’t go into too much detail (you can find more in depth descriptions of the algorithms used on their website), but I will give a very brief overview.
The goal of the optimization is to reduce the number of colors in the image, so the art of the solution lies in how you choose which colors to combine, and which to remove. Several tactics can be employed for the best visual outcome, for example in areas that are more transparent you can be more ruthless because they are more difficult to see, you can use different tactics on areas of the image with different amounts of noise, and instead of choosing colors that occur most often, colors can be chosen with minimal variance between median values.
How does PNGQuant compare?
There are numerous alternatives available whose aim is to reduce PNG file size, for example OptiPNG, PngOptimizer, ImageOptim and PNGQauntlet to name a few. Many do loss-less compression (which means all original data is preserved), but naturally this does not yield results like lossy compression does.
As Java is the language that we produce our libraries in, we were keen to see if there are any good Java alternatives available. Unfortunately, ImageIO in java is notoriously poor at producing well-optimised images. There are gains to be had by using JAI, and there is a Java PNG optimization library called PNGTastic. Here is the results of a non-scientific test to see how they compare:
Optimizer | File Size | % Saving | Time Taken | Difference |
ImageIO | 26.4MB | N/A | 23 Seconds | N/A |
JAI | 19.2MB | 27% | 33 Seconds | 1.5X |
ImageIO then PNGTastic | 18.8MB | 29% | 200 Seconds | 6.5X |
ImageIO then PNGQuant | 7.69MB | 70% | 66 Seconds | 3X |
As you can see, PNGQuant is a clear winner, but that doesn’t stop this process from being expensive, with PNGQuant tripling the test time.
How to use PNGQuant
If you would like to use PNGQuant for your own uses, you can find instructions on their website.
JPDF2HTML5 and JPedal now includes similar functionality to JAI and PngQuant by default as this functionality is built in and utilises the JDeli Image Library custom code, you can learn more in our article on ‘How to generate Smaller PNG files in Java‘. So you should not really need PngQuant when using our software.
This article is part of a series of articles with suggestions for enhancing your HTML5 content. You can also read about Adding Annotations with Annotator.js, Adding Fullscreen using the JavaScript FullScreen API andPassword Protecting content with Apache htaccess.