Log entry (22/09/2023)
The Oculorum nebula has proven to be a strange and unintuitive place. The imagery around me appears to shift and distort in volume, and yet, all attempts to capture this sensation yield nothing of substance; it is though the very particles themselves are sizing me up, ready to-
Okay, that’s enough, let’s get into the data.
Data analysis
To compare the different techniques and tools, I gathered nineteen images of varying colour quantities, image dimensions, and overall complexity, ranging from simple pixel art, to 4K widescreen images.
Showing all the results here would be meaningless, since they tended to be similar, so instead, I’m going to be analysing a useful subset of the images. Here’s a basic rundown of how these results were collected:
- The original image is fed into pngquant, such that if the image can’t be optimised without changing it visually, the input is given as the output (and hence share the same size).
- Concurrently, the original image is fed into oxipng at max settings, and to cwebp in lossless mode.
- Though it’s worth noting that “lossless” may be misleading.
- If pngquant doesn’t duplicate the input image, then the output is fed into oxipng (which is the “Oxi-Quant” entry). Otherwise, the output of oxipng is copied.
Or more precisely, the commands were:
- pngquant --quality 100-100 --speed 1 --strip “$original_image” --output “$path_to_quant_output”
- oxipng --opt max --strip all “$original_image” --out “$path_to_oxi_output” (same options for “Oxi-Quant”)
- Link to OxiPNG GitHub page.
- OxiPNG is a multithreaded version of the previously covered OptiPNG tool, which is not only substantially faster, but generates even more compact image encodings.
- cwebp -z 9 -mt “$original_image” -o “$path_to_cwebp_output”
Lossless AVIF was excluded since, unlike WebP, it doesn’t have a separate encoding scheme for lossless mode, which gave it no chance of winning.
Typical case
For the vast majority of non-pixel-art images, the results looked like this:
And for pixel art images, the results looked like this:
So, pngquant helps a fair bit for pixel art, oxipng does even better in general and isn’t affected by the input being pngquant-optimised, and cwebp consistently takes the victory. Easy to understand and consistent-
Outliers
Other times though, you get results like this:
Unfortunately, cwebp isn’t the most effective tool for every possible case (damnit), however, using just oxipng will instead take the victory in those circumstances… right?
Yeah, sure, or pngquant magically does something that oxipng doesn’t, causing the combo to be more effective than only using oxipng, because that makes sense. Well, then I guess always using both is the right-
Or not.
So, for the most optimal encoding, we would have to use all three tools plus the combo (except for the input-as-output case), and then pick the smallest output. Fun.
Additional notes
- Although WebP lossless mode does preserve the RGBA values of every pixel from the original image (at least when using PNG as the input), it only supports 8-bit RBGA colours which makes it unsuitable for “losslessly” compressing HDR images.
- Passing the “Oxi-Quant” images through cwebp had no effect on the output size compared to just using cwebp.
- For gif2webp, and pixel art GIFs as the input, the output was substantially larger than what gifsicle or gif2apng could achieve, so they’re still the optimal tools.