AVIF: El Formato de Imagen Moderno — Guía Técnica Completa
AVIF (AV1 Image File Format) es un formato de imagen abierto y libre de royalties basado en el códec de vídeo AV1, estandarizado por la Alliance for Open Media (AOM) en 2019. AVIF combina el contenedor ISOBMFF (la misma estructura de boxes usada por MP4 y HEIF) con los algoritmos de codificación intra-frame de AV1 para entregar imágenes significativamente más pequeñas que JPEG, PNG y WebP a la misma calidad perceptual. A fecha de 2024, AVIF es compatible con Chrome, Firefox, Edge, Safari 16+, Android 12+ e iOS 16+.
Estructura del Contenedor: ISOBMFF + HEIF
Los archivos AVIF son contenedores HEIF (High Efficiency Image File Format, ISO 23008-12) que almacenan elementos de imagen AV1. La estructura de nivel superior sigue el layout de boxes ISOBMFF:
ftyp — Box de Tipo de Archivo
major_brand: "avif"
compatible_brands: ["avif", "mif1", "miaf", "MA1B"|"MA1A"]
meta — Box de Metadatos
hdlr — Box de Referencia de Manejador ("pict")
pitm — Box de Elemento Primario (ID del elemento de imagen primario)
iloc — Box de Localización de Elementos (offsets de bytes de cada elemento)
iinf — Box de Información de Elementos
iprp — Box de Propiedades de Elementos
ipco — Contenedor de Propiedades de Elementos
av1C — Box de Configuración del Códec AV1
ispe — Extensiones Espaciales de Imagen (ancho × alto)
pixi — Información de Píxel (bits por canal)
colr — Información de Color (perfil ICC o primarios nclx)
mdat — Box de Datos Multimedia (payload del bitstream AV1 real)
Codificación Intra-Frame AV1 para Imágenes
AVIF usa keyframes de AV1 (frames codificados intra — sin predicción inter de otros frames). Las herramientas de codificación intra de AV1 incluyen:
- 77 modos de predicción intra: direccionales, DC, suave, Paeth y croma-desde-luma
- Tamaños de transformada variables: DCT de 4×4 a 64×64, ADST, FLIPADST, IDENTITY, WHT
- Filtros de bucle: desbloqueo, CDEF, restauración de bucle (filtro Wiener y filtro auto-guiado)
- Síntesis de grano de película: el codificador señaliza parámetros de grano en lugar de codificar el ruido real; el decodificador sintetiza grano visualmente coincidente
- Color de 10/12 bits: supera el límite de 8 bits de JPEG, habilitando HDR y gama de color amplia
- Canal alpha: almacenado como elemento de imagen auxiliar AV1 separado
Soporte de Espacio de Color y HDR
El box colr de AVIF transporta información del espacio de color mediante dos mecanismos:
- Perfil ICC: perfil de color embebido (sRGB, Display P3, ProPhoto RGB, etc.)
- nclx: señaliza valores CICP:
colour_primaries: 1=BT.709/sRGB, 9=BT.2020, 12=Display P3transfer_characteristics: 1=BT.709, 16=PQ (SMPTE ST 2084/HDR10), 18=HLGmatrix_coefficients: 0=identidad/RGB, 1=BT.709, 9=BT.2020 NCL
Codificación con FFmpeg y libavif
# Convertir JPEG/PNG a AVIF con ffmpeg
ffmpeg -i entrada.jpg \
-c:v libaom-av1 \
-still-picture 1 \
-crf 23 \
-cpu-used 8 \
salida.avif
# Usando avifenc (codificador de referencia libavif — mejor control de calidad)
avifenc --min 20 --max 30 --speed 6 entrada.png salida.avif
# --min/--max: rango del cuantificador (0=sin pérdida, 63=peor)
# --speed 0-10: 0=más lento/mejor, 10=más rápido/peor (por defecto 6)
# AVIF sin pérdida
avifenc --lossless entrada.png salida_sin_perdida.avif
# AVIF de 10 bits con perfil Display P3
avifenc --depth 10 --cicp 12/13/6 --speed 4 entrada_p3.png salida_hdr.avif
# Conversión por lotes de PNG a AVIF
for f in *.png; do
avifenc --min 20 --max 30 --speed 6 "$f" "${f%.png}.avif"
done
Procesamiento AVIF con Python
from PIL import Image
# Requiere: pip install Pillow pillow-avif-plugin
# O Pillow >= 9.1.0 con soporte AVIF incorporado (en plataformas con libavif)
# Abrir AVIF
img = Image.open('foto.avif')
print(f"Tamaño: {img.size}, Modo: {img.mode}")
# Convertir JPEG a AVIF
img = Image.open('foto.jpg').convert('RGB')
img.save(
'foto.avif',
format='AVIF',
quality=80, # 0–100 (mayor = mejor calidad = archivo más grande)
speed=6, # 0–10 velocidad de codificación (0=más lento, mejor calidad)
)
# Guardar con transparencia (RGBA → AVIF con alpha)
img_rgba = Image.open('logo.png').convert('RGBA')
img_rgba.save('logo.avif', format='AVIF', quality=85)
# Conversión por lotes de un directorio
import pathlib
for src in pathlib.Path('imagenes/').glob('*.jpg'):
img = Image.open(src).convert('RGB')
dst = src.with_suffix('.avif')
img.save(str(dst), format='AVIF', quality=80, speed=6)
print(f"{src.name} → {dst.name} "
f"({src.stat().st_size//1024} KB → {dst.stat().st_size//1024} KB)")
AVIF vs JPEG vs WebP vs HEIC
| Característica | JPEG | WebP | AVIF | HEIC |
|---|---|---|---|---|
| Compresión vs JPEG | 1× | ~30% mejor | ~50% mejor | ~50% mejor |
| Canal alpha | No | Sí | Sí | Sí |
| Sin pérdida | No | Sí | Sí | Sí |
| HDR / 10 bits | No | No | Sí | Sí |
| Animación | No | Sí | Sí | Sí |
| Síntesis de grano | No | No | Sí | No |
| Libre de royalties | Sí | Sí | Sí | No |
| Chrome | ✓ | ✓ | ✓ (v85+) | Limitado |
| Firefox | ✓ | ✓ | ✓ (v93+) | No |
| Safari | ✓ | Limitado | ✓ (16+) | ✓ |
Servir con <picture> y Fallback HTML
<picture>
<!-- Navegadores modernos: AVIF primero (más pequeño) -->
<source srcset="foto.avif" type="image/avif">
<!-- Fallback: WebP para navegadores sin AVIF -->
<source srcset="foto.webp" type="image/webp">
<!-- Fallback universal: JPEG -->
<img src="foto.jpg" alt="Descripción de la imagen" width="1200" height="800"
loading="lazy" decoding="async">
</picture>
Errores Comunes
- La codificación AVIF es lenta. libaom-av1 a velocidad 0–4 produce excelente calidad pero tarda segundos por imagen. Para pipelines de producción, usa velocidad 6+ o considera codificadores alternativos como SVT-AV1 vía
avifenc. Precomputa todos los archivos AVIF en tiempo de compilación/subida. - Safari < 16 no soporta AVIF. Proporciona siempre fallbacks JPEG o WebP mediante
<picture>o negociación de contenido. - La escala del cuantificador es contraintuitiva. En
avifenc,--min 0 --max 0significa sin pérdida; valores más altos significan peor calidad. Esto es lo opuesto a la calidad JPEG (basada en porcentaje, mayor = mejor).
Conversiones relacionadas
Lo más habitual al trabajar con imágenes son estas direcciones de conversión: