Skip to content

AVIF and HEIF encoding, bit depth, and speed/effort tuning

Copy page

AVIF stores AV1 intra-coded frames inside a HEIF (ISO Base Media File Format) container. At comparable visual quality, AVIF typically saves 40%–50% over JPEG and 15%–25% over WebP, while supporting 8-bit, 10-bit, and 12-bit depth and wide-gamut HDR profiles.

In libvips, both AVIF and HEIC/HEIF are handled by heifload / heifsave (delegating via libheif to aom, rav1e, or svt-av1) with compression="av1".

Setting govips AvifExportParams sharp .avif(options) pyvips / vips CLI heifsave Production guidance
Quality factor Quality (default 80) quality (default 50) Q=55 / --Q 55 Watch the default difference: AVIF is highly efficient; 50–65 roughly matches JPEG 80–85
Encoding speed / effort Effort (0..9, default 5; legacy Speed is deprecated) effort (0..9, default 4) effort=4 / --effort 4 Same direction on libvips >= 8.13: 0 is fastest, 9 is slowest/best compression (use 3–5 for real-time services)
Lossless mode Lossless: true lossless: true lossless=True / --lossless Lossless AVIF is slower and often larger than lossless WebP
Bit depth Bitdepth (8 / 10 / 12) bitdepth (8 / 10 / 12) bitdepth=8 8 has universal browser support; 10/12 suits HDR and wide-gamut workflows
Chroma subsampling — (AvifExportParams does not expose subsample_mode) chromaSubsampling (default '4:4:4') subsample_mode In sharp, pyvips, and CLI, set '4:2:0' (or on) for photography to reduce size and improve hardware decode compatibility
package main
import (
"fmt"
"os"
"github.com/davidbyttow/govips/v2/vips"
)
func main() {
if err := vips.Startup(nil); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
defer vips.Shutdown()
// Check whether the linked libvips build includes AVIF support
if !vips.IsTypeSupported(vips.ImageTypeAVIF) {
fmt.Fprintln(os.Stderr, "AVIF is not supported by this libvips build")
os.Exit(1)
}
image, err := vips.NewImageFromFile("input.jpg")
if err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
defer image.Close()
params := vips.NewAvifExportParams()
params.Quality = 55
params.Bitdepth = 8
params.Effort = 4 // 0..9, lower is faster (NewAvifExportParams default is 5)
params.StripMetadata = true
data, _, err := image.ExportAvif(params)
if err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
if err := os.WriteFile("output.avif", data, 0o644); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}
  1. Streaming boundary in govips v2.19.0: govips provides SaveToWriterHeif(w, heifParams) but does not have a dedicated SaveToWriterAvif method; use image.ExportAvif(avifParams) (or SaveToWriter with Format: vips.ImageTypeAVIF in ExportParams).
  2. libheif plugin availability: many Linux distributions build libheif with AV1 plugins enabled (supporting .avif) while omitting patent-encumbered HEVC/x265 encoders (so .heic export fails with Unsupported compression). See Missing codecs and unsupported formats for diagnostics.