Recently I wondered what PNG compression engine was the best. I had been using pngcrush out of habit, but was there a better compressor out there? As it turns out, yes. Some initial digging revealed that PNGOUT was apparently pretty good. While it was originally created for Windows, there are ports available for other operating systems. Unfortunately, PNGOUT (and those ports) are under a non-free license, and “The source code for these tools is not public. Don’t bother asking.". So: is PNGOUT the best compression engine? Let’s find out!
Testing the engines
I compared 10 PNG compression engines: zopflipng, pngout, FFmpeg, pngcrush, imagemagick, optipng, oxipng, ImageWorsener, AdvanceCOMP, and pngrewrite. For engines that supported it, I set the compression amount to the highest possible. I also turned off the optimization where you just do nothing if your attempt to compress the image makes it bigger, since that’s a boring optimization that everyone implements anyways. I only measured how much the engines could compress input files: I didn’t measure how long that took. For images that are served a lot, compression that takes a long time is worth it, since you can compress it up-front to get savings over time. Maybe in the future I’ll factor in the speed of performing the compression.
I sourced test images from:
- Popular images on Wikimedia Commons
- Popular images on Wikimedia Commons with the “Convert to SVG” tag
- The pngsuite, a suite of images for testing PNG implementations
In total, this amounted to 336 test images.
I was quite suprised at the results I got once I finished adding support for all engines to my test harness. The best engine, by a long shot, was Zopfli, a compression engine by Google. It only supports compressing images, so you have to use something else to decompress them. They say:
Zopfli Compression Algorithm is a compression library programmed in C to perform very good, but slow, deflate or zlib compression.
And it is indeed very good: it blows all of the other compression engines out of the water. Just look at the comparision table of how each engine does on each image: Zopfli is almost always the best. On average, it can shave 33.4% off of images, while the runner-up, PNGOUT, can only do 17.86%! (yes, some engines indeed make images worse on average, usually due to weird images in the pngsuite being hard to compress):
(it was a real pain to get LibreOffice Calc to make that chart, the chart interface is not remotely intuitive)
Of the engines, ImageMagick, and FFmpeg were never the best engine to compress an image. The best pngrewrite, optipng, and oxipng could do is tie for best with Zopfli (and usually they do much worse). ImageWorsener, PNGOUT, pngcrush, and AdvanceCOMP could sometimes beat Zopfli, but are usually only a few percent better, and only occasionally: Zopfli is the best 87% of the time. The images it tends to be a bit worse on are typically “weird” images that are hard to compress.
So Zopfli is really good. You should use it to compress your images! The catch, of course, is that it’s very slow. Running Zopfli on all user-generated content might not be a good idea, but compressing your static images can help save a lot of bandwidth! And you can save bandwidth: all of the (valid) images in the test suite could be further compressed by at least one engine, and there was only one image that Zopfli was unable to shrink further.
The Nix package manager was quite useful for performing this analysis. nixpkgs had almost all of the engines I needed, already up-to-date. There wasn’t any messing around with dependencies! The one compression engine that nixpkgs any didn’t have, pngrewrite, was super-simple to use: I just wrote a short expression to tell Nix how to build it, and Nix handled everything else for me. Take a look at the
*.nix files in the test harness for more details.