images: Make AVIF chroma subsampling content-aware via the hint

Encode photo/picture hints (and the default) as YUV420 instead of YUV444,
keeping 444 for text/icon/drawing. Lossless stays 444.

This roughly halves the encoder's peak memory (42 -> 27 MiB/MP) and the
output size, while 444 remains available for sharp-edged content. A
3000x3000 image now needs ~239 MiB to encode, down from ~381 MiB (which
sat right at the 384 MiB WASM cap).

Closes #14987

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Bjørn Erik Pedersen
2026-06-04 15:00:28 +02:00
parent 248241b6e1
commit 341f575d2d
14 changed files with 52 additions and 4 deletions
+1
View File
@@ -144,6 +144,7 @@ func (d *Codec) EncodeTo(conf ImageConfig, w io.Writer, img image.Image) error {
"compression": conf.Compression,
"quality": conf.Quality,
"encoderSpeed": conf.EncoderSpeed,
"hint": conf.Hint,
}
return d.avif.Encode(w, img, opts)
case WEBP:
+3 -3
View File
@@ -104,7 +104,7 @@ var compressionMethods = map[string]bool{
"lossless": true,
}
// These encoding hints are currently only relevant for Webp.
// These encoding hints are used by Webp (preset) and Avif (chroma subsampling).
var hints = map[string]bool{
"picture": true,
"photo": true,
@@ -429,7 +429,7 @@ type ImageConfig struct {
BgColor color.Color
// Hint about what type of picture this is. Used to optimize encoding
// when target is set to webp.
// when target is webp (preset) or avif (chroma subsampling).
Hint string
Compression string
@@ -510,7 +510,7 @@ type ImagingConfig struct {
ResampleFilter string
// Hint about what type of image this is.
// Currently only used when encoding to Webp.
// Used when encoding to Webp (preset) and Avif (chroma subsampling).
// Default is "photo".
// Valid values are "picture", "photo", "drawing", "icon", or "text".
// Moved to WebpConfig in v0.155.0, but kept here for backwards compatibility.
Binary file not shown.

Before

Width:  |  Height:  |  Size: 44 KiB

After

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 41 KiB

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.5 KiB

After

Width:  |  Height:  |  Size: 9.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.9 KiB

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 39 KiB

After

Width:  |  Height:  |  Size: 38 KiB