Pillow
Pillow es el fork mantenido de PIL, la biblioteca estándar para abrir, convertir, redimensionar, recortar y guardar imágenes en pipelines de Python, manejadores de carga web y preprocesamiento de ML.
Busca en todas las páginas de la documentación
Pillow es el fork mantenido de PIL, la biblioteca estándar para abrir, convertir, redimensionar, recortar y guardar imágenes en pipelines de Python, manejadores de carga web y preprocesamiento de ML.
from PIL import Image
with Image.open("photo.jpg") as img:
img = ImageOps.exif_transpose(img)
img.thumbnail((800, 800))
img.save("preview.webp", format="WEBP", quality=85)Cuándo usar esto:
from __future__ import annotations
from io import BytesIO
from pathlib import Path
from PIL import Image, ImageOps, UnidentifiedImageError
MAX_BYTES = 5 * 1024 * 1024
ALLOWED = {"JPEG", "PNG", "WEBP"}
def make_thumbnail(data: bytes, max_edge: int = 256) -> bytes:
if len(data) > MAX_BYTES:
raise ValueError("file too large")
try:
with Image.open(BytesIO(data)) as img:
if img.format not in ALLOWED:
raise ValueError(f"unsupported format {img.format}")
img = ImageOps.exif_transpose(img)
img = img.convert("RGB")
img.thumbnail((max_edge, max_edge))
out = BytesIO()
img.save(out, format="WEBP", quality=80, method=6)
return out.getvalue()
except UnidentifiedImageError as exc:
raise ValueError("not an image") from exc
if __name__ == "__main__":
sample = Path("photo.jpg").read_bytes()
Path("thumb.webp").write_bytes(make_thumbnail(sample))Lo que esto demuestra:
exif_transpose corrige las fotos de teléfono rotadasconvert("RGB") normaliza los modos antes de la exportación a WEBPBytesIO en memoria para manejadores de APIRGB, RGBA, L (escala de grises), P (paleta) - convertir antes de formatos que no soportan alfa.resize, thumbnail, crop, rotate, módulo filter para desenfoque/nitidez.format=; la configuración de calidad varía según el códec.| Tarea | API |
|---|---|
| Caja delimitadora máxima | thumbnail((w, h)) |
| Dimensiones exactas | resize((w, h), Image.Resampling.LANCZOS) |
| Eliminar EXIF | img.getexif().clear() o guardar sin exif |
| Dibujar texto | ImageDraw.Draw(img).text(...) |
# Verificar dimensiones sin decodificación completa (donde sea compatible)
with Image.open(path) as img:
width, height = img.sizeImageOps.exif_transpose.convert("RGB") sobre un fondo blanco primero.img.format después de abrir.| Alternativa | Usar Cuando | No Usar Cuando |
|---|---|---|
wand (ImageMagick) | Rasterización compleja de PDF/PSD/SVG | Dependencias más simples (se requiere binario de ImageMagick) |
opencv-python | Pipelines de CV, detección de rostros | Microservicio simple de miniaturas |
torchvision.transforms | Solo aumentación en tiempo de entrenamiento | Sanitización general de cargas |
| CDN de imágenes SaaS | Descargar transformaciones en el borde | Entornos aislados o cargas sensibles al costo |
Requiere el plugin pillow-heif; de lo contrario, convierte en el cliente o rechaza con un error claro.
Mantén el modo RGBA; no conviertas a RGB antes de guardar.
Sí, con construcciones de capa delgadas; ten cuidado con el tamaño del paquete y las dependencias de bibliotecas nativas.
Usa Image.alpha_composite con una capa de marca de agua PNG transparente.
Image.Resampling.LANCZOS para reducir; NEAREST para pixel art.
Elimina el EXIF de ubicación en las cargas de usuario antes de publicarlo; requisito de privacidad.
Las versiones recientes de Pillow agregan AVIF si libavif está presente; verifica en la imagen de despliegue de destino.
Genera un PNG de color sólido de 10x10 en las pruebas mediante Image.new("RGB", (10, 10), "red").
No compartas objetos Image mutables entre hilos; abre por tarea.
data = await file.read() luego pasa los bytes al pipeline BytesIO con límites de tamaño.
Versiones de Stack: Esta página fue escrita para Python 3.14.0 (estable 3.14, mantenimiento 3.13), FastAPI 0.115+, Django 5.2, Flask 3.1, Pydantic 2, PyTorch 2.6+, pandas 2.2+, Polars 1.x, ruff 0.9+, y uv 0.6+.
Revisado por Chris St. John·Última actualización: 19 jul 2026