The average speed of a modern internet connection would sound very futuristic to web masters of the past. Back in the early days of the web, the amount of transferred data was crucial, both in terms of time and cost, therefore everyone involved in hosting something online tried to make images smaller.
In this tutorial, we will find out the ways you can slim down bitmap files for the web. As long as it utilises the good old PNG and JPEG formats, we'll see how we can make them smaller without compromising quality, using some hot open source projects. In the end, we'll have substantially smaller files that will still look good but require less time and data to get rendered in users' web browsers.
Read on to dive into the details. First, a quick note on software. All the tools mentioned here are open source – jump to the bottom for a guide to how to get the software you need.
Choose the right format
It may sound trivial to still be harking on about file size, yet there are enough examples where an image is either too massive without any purpose or looks terrible despite being small. To avoid such mistakes, choose a format to save or convert an image wisely. Using JPEG implies breaking an image into tiles of 8x8 pixels, where each tile gets compressed. The level of compression depends on the user (it's that slider when you save an image) but typically JPEG allows for 10:1 file size gain with an acceptable loss in quality.
The perceptual difference between JPEG files made with high (80-100) and low (40-60) compression ratio is minimal for photographic images but highly noticeable for things such as digital artwork, icons and screenshots. Therefore it is recommended to choose JPEG for photos and go with something else for the other types of bitmap images.
PNG is one of the most suitable formats for network graphics (actually, that's what its abbreviation means). While the JPEG format is always lossy (even with quality set to 100), the PNG format can be either lossy or not. Moreover, even when it is, it compresses data by reducing the number of colours used in the image, so that the result commonly still looks crisp and clear. So choose PNG for depicting screengrabs or any other sort of pictures with solid fill.
Start with convenient methods
Optimising bitmap files is possible with a bunch of freeware tools, so you don't have to rely on a full-fledged image editor. Imagine is one such application and it is incredibly easy to use. Just drag an image (or a stack of images) over the Imagine window and use the little sliders to adjust compression ratio.
Imagine works with JPEG, PNG and WebP files and it is ideal for lossy encoding. The biggest advantage is that the tool is interactive; it instantly shows you how the image will look with the current settings and displays the proposed file size. Imagine works great for batch processing – at least it can save all opened images at once if you need to.
Needless to say, there are dozens, if not hundreds, of other JPEG and PNG optimisers, including some handy online services (like TinyJPG). But don't rush off just yet – we've got something better up our sleeve.
Advanced compression techniques
At first sight, it looks like we can't take much more of a bite out of lossy JPEG file sizes, something that can be instantly proven by futile attempts to further archive images using ZIP or any other compressing technique. But here comes Guetzli, a smart Swiss cookie and sophisticated perceptual encoder for JPEG.
Guetzli makes an average JPEG smaller by 20 to 30 per cent by increasing its compression density. The secret is that the algorithm is aware of the way humans perceive what they see, so the resulting image still looks great to the eye. Guetzli is a cross-platform command-line tool, which uses the following syntax:
guetzli [--quality Q] [--verbose] original_image output_jpeg_image
The original image can be either PNG or JPEG, while the output is always JPEG. Therefore, you can use Guetzli to convert PNG to JPEG thanks to its state-of-the-art compression. The quality should fall between 0-100. Guetzli is an incredibly resource-heavy software; it consumes nearly 300MB of memory per 1 megapixel and also a lot of CPU power. We hope your super-optimised JPEGs will not boost global warming…
Portable network graphics are a different story, as long as it was designed for lossless image encoding. When you save an image as PNG in an image editor like GIMP, you have a compression ratio slider with values from 0 to 9. Here 0 means no compression and it makes the image weigh as if it was saved as a TIFF. In contrast, 9 strips away most of the unneeded colour information and results in a file that is 15-20 times smaller than TIFF.
This time we'll try to make an already small PNG file (with ratio of 9) even smaller. For this purpose, we'll use Zopfli, another open-source tool that again has roots in Google Labs. Zopfli is a high-quality compressor for Deflate, Gzip and zlib data encoding.
The interesting part is that Zopfli contains two encoders in one bundle: the general-purpose binary and the dedicated 'zopflipng' tool. The latter is exactly what we need! Zopflipng is a Deflate-based encoder with certain algorithms backported from the WebP format. It is smart enough to automatically choose the best strategy using scanline codes and removing various unnecessary chunks inside PNG. Use it with this simple syntax:
zopflipng original_png output_png
Zopflipng can probably do the job even better with the following explicit options:
zopflipng --iterations=500 --filters=01234mepb --lossy_8bit --lossy_transparent original_png output_png
The price you pay is the same as with Guetzli: the tool takes a lot of time to process an image, especially if it is large. The more iterations you use, the longer it will take but 500 is a reasonable number. The file size gain with Zopfli lies between 8 to 20 per cent, which is very good for visually perfect images. In brief, gaining 8 per cent is common for screenshots, whereas 20 per cent is possible with photographs (when you need to store them as PNGs).
Upgrade to next-gen file formats
Formally, this part goes beyond the scope of PNG and JPEG but it is very practical, since you can organise file conversion on-the-fly. What we mean here is using alternative and new image formats that outperform the best industry standards (read WebP).
One is FLIF, a new lossless image format based on the MANIAC (Meta-Adaptive Near-zero Integer Arithmetic Coding) compression method, which can outperform PNG, FFV1, lossless WebP, lossless BPG and lossless JPEG 2000 in terms of compression ratio. FLIF is available for all platforms and some image viewers already support it but it has a long way to go to hit the mainstream. Right now, it makes sense using FLIF for storage or on the server side. It can act like an efficient archiving format. You'll need to grab the code from the project's GitHub page and compile it. Once you have the flif binary installed, use the following command to encode a PNG image:
flif -e original_png output_flif
Replace -e with -d and put the files in reverse order to 'uncompress' your image back to PNG. In terms of tools, right now there are the FLIF WIC API component for Windows, the Qt FlIF plugin for Linux and the Phew image viewer and the QuickLook plugin for macOS (see the links section for details). Compared to the image that was previously tortured by Zopflipng, FLIF reduces its file size further down by ~10 per cent. Impressive results!
Our last hero is Lepton, another open-source format generously published by the Dropbox developers. Lepton does with JPEG what FLIF does with PNG. Lepton can slim down JPEGs by up to 22 per cent in the lossless mode, meaning that the encoder does not cause any loss in quality compared to the original JPEG file. Under the hood Lepton implies smart techniques of compressing those 8x8 JPEG blocks. Instead of writing zeros and ones, Lepton encodes bitmap data using the VP8 arithmetic coder, which respects context around each block.
Our test proved Lepton to be very efficient and fast. The command looked like the following:
lepton original.jpg output.lep
And in a second or two the tool produced the .lep file that was smaller by nearly one quarter of the original. Compared to the time-consuming Guetzli, Lepton is blazingly fast. You can use Lepton the same way Dropbox does. The format enables you to reduce storage costs by 20 to 25 per cent and since it is so snappy, you can do on-the-fly encoding/decoding sequences without major drawbacks. By the way, the decoding command is equally simple, it only needs to swap the two files and the resulting file is identical to the original JPEG:
lepton original.lep output.jpg
Use the described techniques to optimise user data storage or further improve loading speeds of your web projects.
How to get the software
Every piece of software described in this tutorial is open source, so you can use it freely. There is no need to bother compiling everything from sources, as most of the tools below have binary downloads. Here is how to get the software up and running.
Grab the Guetzli binary here. It's the easiest thing to do. Zopfli only gives the code (build it with 'make') at GitHub. However, it may be wiser for you to get it through the node.js Package Manager:
npm install node-zopfli
Some helpful links for FLIF:
- FLIF-hub: Reference implementation, sources and Windows binaries
- XnView MP: A cross-platform photo viewer with built-in FLIF support
- qt-flif-plugin: A heaven for Linux users
- Phew: A viewer and QuickLook plug-in for macOS
- Lepton: Source code and Windows binaries