AVIF (AV1 Image File Format) es el formato de imagen derivado del códec de vídeo AV1. Desarrollado por la Alliance for Open Media, ofrece la mejor relación calidad/tamaño entre los formatos web actuales, superando a WebP y JPEG en la mayoría de escenarios.
## Comparativa de formatos de imagen web
| Formato | Año | Compresión | Transparencia | HDR | Animación | Soporte navegadores |
|---|---|---|---|---|---|---|
| JPEG | 1992 | Buena | No | No | No | 100 % |
| PNG | 1996 | Sin pérdida | Sí | No | No | 100 % |
| WebP | 2010 | Muy buena | Sí | No | Sí | 96 % |
| **AVIF** | **2019** | **Excelente** | **Sí** | **Sí** | **Sí** | **93 %** |
| JPEG XL | 2022 | Excelente | Sí | Sí | Sí | ~30 % |
**AVIF típicamente logra archivos 30–50 % más pequeños que WebP a calidad equivalente**, y hasta 80 % más pequeños que JPEG.
## Soporte de navegadores (2024)
```
Chrome 85+ ✅ nativo
Firefox 93+ ✅ nativo
Safari 16+ ✅ nativo (macOS Ventura / iOS 16)
Edge 121+ ✅ nativo
Opera 71+ ✅ nativo
IE 11 ❌ sin soporte
```
Con 93 % de cobertura, AVIF ya es seguro para producción con fallback a WebP/JPEG.
## HTML con fallback progresivo
```html
```
## Convertir con FFmpeg
FFmpeg ≥ 4.3 incluye soporte AVIF a través del códec `libaom-av1`:
```bash
# JPEG/PNG → AVIF básico
ffmpeg -i entrada.jpg -c:v libaom-av1 -crf 30 -b:v 0 salida.avif
# Controlar calidad (CRF: 0=mejor calidad, 63=peor)
# Rango recomendado: 20-40
ffmpeg -i entrada.png -c:v libaom-av1 -crf 23 -b:v 0 salida.avif
# Velocidad de codificación (cpu-used: 0=lento/mejor, 8=rápido/peor)
# Para producción: 4-6. Para máxima calidad: 0-2
ffmpeg -i entrada.jpg \
-c:v libaom-av1 \
-crf 28 \
-b:v 0 \
-cpu-used 4 \
-row-mt 1 \
salida.avif
# Convertir imagen PNG con transparencia
ffmpeg -i logo.png -c:v libaom-av1 -crf 25 -b:v 0 logo.avif
```
## Convertir con Pillow (Python)
```python
# pip install pillow pillow-avif-plugin
# Pillow >= 9.1.0 incluye soporte AVIF nativo en algunas plataformas
from PIL import Image
# Abrir y guardar como AVIF
img = Image.open('imagen.jpg')
img.save('imagen.avif', format='AVIF', quality=80)
# quality: 0-100 (100 = mejor calidad, mayor tamaño)
# El parámetro se mapea internamente al CRF de AV1
# Verificar formato soportado
from PIL import features
print(features.check_codec('avif')) # True si disponible
# Convertir con tamaño máximo y calidad ajustada
def jpg_a_avif(entrada, salida, calidad=75, max_ancho=1920):
img = Image.open(entrada)
if img.width > max_ancho:
ratio = max_ancho / img.width
nuevo_alto = int(img.height * ratio)
img = img.resize((max_ancho, nuevo_alto), Image.LANCZOS)
img.save(salida, format='AVIF', quality=calidad)
return salida
jpg_a_avif('foto.jpg', 'foto.avif', calidad=80)
```
## Conversión masiva con Python
```python
import os
from pathlib import Path
from PIL import Image
def convertir_directorio_a_avif(directorio, calidad=78):
origen = Path(directorio)
extensiones = {'.jpg', '.jpeg', '.png', '.webp'}
resultados = []
for archivo in sorted(origen.iterdir()):
if archivo.suffix.lower() not in extensiones:
continue
destino = archivo.with_suffix('.avif')
try:
img = Image.open(archivo)
img.save(destino, format='AVIF', quality=calidad)
tam_orig = os.path.getsize(archivo)
tam_avif = os.path.getsize(destino)
ahorro = (1 - tam_avif / tam_orig) * 100
resultados.append({
'archivo': archivo.name,
'original_kb': tam_orig // 1024,
'avif_kb': tam_avif // 1024,
'ahorro_pct': round(ahorro, 1),
})
print(f"OK: {archivo.name} → {tam_orig//1024} KB → {tam_avif//1024} KB ({ahorro:.0f}% menos)")
except Exception as e:
print(f"ERROR: {archivo.name}: {e}")
return resultados
stats = convertir_directorio_a_avif('imagenes/')
ahorro_medio = sum(r['ahorro_pct'] for r in stats) / len(stats) if stats else 0
print(f"\nAhorro medio: {ahorro_medio:.1f}%")
```
## Configuración óptima por caso de uso
| Caso de uso | CRF (ffmpeg) | quality (Pillow) | Notas |
|---|---|---|---|
| Fotografía web | 30–35 | 70–80 | Equilibrio tamaño/calidad |
| Thumbnails | 38–45 | 55–65 | Priorizar tamaño pequeño |
| Imagen de producto | 22–28 | 82–90 | Máxima calidad visible |
| Fondo/hero banner | 32–38 | 65–75 | El usuario apenas los inspecciona |
| Iconos / gráficos | 18–25 | 85–95 | Sin pérdida perceptible |
## AVIF en Next.js / Astro
```js
// next.config.js — habilitar AVIF automático
module.exports = {
images: {
formats: ['image/avif', 'image/webp'],
},
}
// Next.js convierte y sirve AVIF automáticamente con
// Astro — ya incluye soporte AVIF con @astrojs/image
// astro.config.mjs
import { defineConfig } from 'astro/config';
export default defineConfig({
image: { service: { entrypoint: 'astro/assets/services/sharp' } }
});
```
## Cuándo usar AVIF
**Usa AVIF para:**
- Fotografías e imágenes ricas en color en sitios modernos
- Sitios donde el rendimiento y Core Web Vitals son prioritarios
- Imágenes hero, galerías y páginas de producto
**Añade siempre fallback WebP + JPEG** usando `` para navegadores sin soporte, especialmente Safari < 16 e iOS < 16.