lovell / sharp

High performance Node.js image processing, the fastest module to resize JPEG, PNG, WebP, AVIF and TIFF images. Uses the libvips library.
https://sharp.pixelplumbing.com
Apache License 2.0
28.96k stars 1.29k forks source link

AVIF. Refactor default for `chromaSubsampling` option #3589

Open o-alexandrov opened 1 year ago

o-alexandrov commented 1 year ago

Feature request

What are you trying to achieve?

For AVIF output, set chromaSubsampling automatically, instead of depending on the user to select correct chromaSubsampling for a particular image.

afaik, sharp doesn't upscale (increase the number of colors) chromaSubsampling when converting 4:2:0 input to 4:4:4 output. So there's no visual benefit in outputting 4:4:4 for the 4:2:0 input.

When you searched for similar feature requests, what did you find that might be related?

What would you expect the API to look like?

No public facing API changes. Internally, sharp or libvips should dynamically set chromaSubsampling based on the metadata of the input, if chromaSubsampling override is not provided.

lovell commented 1 year ago

This will depend on #3584. A PR to implement this in libvips is welcome, if you're able.

If this is to be "automagic", then setting lossless or a high-enough quality should also default to 4:4:4.

So there's no visual benefit in outputting 4:4:4 for the 4:2:0 input.

This might be the case for a simple roundtrip decode/encode when there are no other operations e.g. no resizing, and no change in quality/lossless settings, but I'm unsure how common this is.

Use of AVIF subsampling results in visible blocks on edges, especially around red/orange areas, and I suspect the implementation favours human perception of video rather than still images. My recommendation for AVIF is to use 4:4:4 always.

o-alexandrov commented 1 year ago

Thank you, I agree the case is too rare to bother, if together with a change in quality, the number of colors might increase when outputting 4:4:4 from 4:2:0. However, based on my manual observation, I haven't seen a visual difference in this case also.

This tool also states there is no visual difference.

Using sharp, applying:

.rotate() // to apply rotation based on exif metadata
.avif({
  quality: 64,
  effort: 1,
  chromaSubsampling: 4:4:4 and 4:2:0 // see output examples in the zip file
})

Adding a zip file to ensure GitHub won't process images here.

example-image.zip