Perceptual image encoding?

I opened this thread to gauge interest in / check feasibility of implementing some kind of perceptual image encoding in Zola for the resize_image() function.

Rationale / Explanation

Lossy image compression is generally a trade-off between visual fidelity and filesize. Most formats (webp and jpeg included) allow tweaking this using some kind of ‘quality’ scale that configures how aggressive the lossy parts of the compression pipeline are.

The issue with this, is that blurry or smooth images can be compressed much more heavily before they show any perceptible quality loss compared to images with lots of fine detail. As a result, setting a single quality level for all images in a set almost always results in low detail images being encoded with a larger than necessary filesize, or high detail images showing visible compression artefacts.

Different formats also have different quality scales, and a quality 80 jpeg will have a totally different quality / filesize relationship than a webp encoded at quality 80. A good look at this difference.

There are several projects that try and work around this by using a algorithm called SSIM (structural similarity index measure) which tries to more accurately reflect the way the human eye perceives visual differences (a score of 1 would be no perceptible differences, and 0 completely different). They then take a target SSIM value, and perform multiple encodes with different quality levels and compare the new image to the original to find the one that most closely matches the SSIM value with the smallest filesize.

Some examples of tools that do this are: pio, jpeg-recompress and guetzli.

Obviously, building such a tool from scratch would be an awful lot of work, but I wonder whether it might be possible to integrate with a tool such as pio?

Advantages

  • Closer to optimal filesize / visual quality ratio for all images. Thus better performance as less wasted bytes for images.
  • Could set a single quality value for jpeg and webp and have images with much closer visual fidelity.
  • Quality settings that feel more intuitive.

Disadvantages

  • Much longer encode times, or having to maintain a completely seperate image encoding path.
  • Possibly a lot of work to implement

If Zola ever did decide to implement such a feature, the hugely increased encode times for images would probably warrant putting it behind some kind of configuration flag.

There is already an issue for adding Pio support: Feature Request: Image Optimization with Pio · Issue #1429 · getzola/zola · GitHub

Thanks Keats. I managed to miss that one somehow.