Tutorial

Tutorial: crear thumbnails automáticos para tu galería

13 Nov 2025 Por enguillem 3 min de lectura

0) Crea un entorno de desarrollo

Antes de ejecutar nada, es buena práctica trabajar dentro de un entorno virtual de Python.

Crea una carpeta de proyecto y un entorno de desarrollo:

mkdir aplicaciones_python
cd aplicaciones_python

# Crea el entorno virtual
python3 -m venv .venv

# Actívalo (Linux/Mac)
source .venv/bin/activate

# En Windows PowerShell
.venv\Scripts\activate

1) Requisitos

  • Python 3.9+
  • Pillow
pip install pillow

2) Guarda el script

Crea un fichero llamado resize_thumb.py con este contenido:

#!/usr/bin/env python3
import argparse
from pathlib import Path
from PIL import Image, ImageOps

THUMB_THRESHOLD = 1200   # si el ancho > 1200px, se crea .thumb
THUMB_WIDTH = 600        # ancho del thumbnail
SUFFIX = ".thumb"
EXTS = {".jpg", ".jpeg", ".png", ".webp", ".tif", ".tiff"}

def thumb_name(p: Path) -> Path:
    return p.with_name(p.stem + SUFFIX + p.suffix.lower())

def save_image(img, out, fmt):
    fmt = (fmt or p.suffix.lstrip(".")).upper()
    if fmt in ("JPEG","JPG"):
        img.save(out, format="JPEG", quality=80, optimize=True, progressive=True)
    elif fmt == "PNG":
        img.save(out, format="PNG", optimize=True)
    elif fmt == "WEBP":
        img.save(out, format="WEBP", quality=80, method=6)
    else:
        img.save(out)

def process(p: Path):
    try:
        with Image.open(p) as im:
            im = ImageOps.exif_transpose(im)  # respeta orientación EXIF
            w, h = im.size
            if w <= THUMB_THRESHOLD:
                return
            r = THUMB_WIDTH / float(w)
            new = (THUMB_WIDTH, max(1, int(h * r)))
            out_img = im.resize(new, Image.Resampling.LANCZOS)
            out_path = thumb_name(p)
            if out_path.exists() and out_path.stat().st_mtime >= p.stat().st_mtime:
                return  # ya existe y está actualizado
            save_image(out_img, out_path, im.format)
            print(f"Thumbnail: {out_path.name} {new[0]}x{new[1]}")
    except Exception as e:
        print(f"Error con {p}: {e}")

def main():
    ap = argparse.ArgumentParser(description="Genera .thumb si el ancho > 1200px.")
    ap.add_argument("--folder", required=True, help="Carpeta con imágenes")
    args = ap.parse_args()

    folder = Path(args.folder).expanduser().resolve()
    if not folder.is_dir():
        print("Carpeta no válida"); return

    for p in sorted(folder.iterdir()):
        if p.is_file() and p.suffix.lower() in EXTS and SUFFIX not in p.stem:
            process(p)

if __name__ == "__main__":
    main()

Personaliza THUMB_THRESHOLD, THUMB_WIDTH y SUFFIX si lo necesitas.

3) Ejecutar

  • Linux/macOS:
python3 resize_thumb.py --folder /ruta/a/imagenes
  • Windows (PowerShell):
python .\resize_thumb.py --folder "C:\ruta\a\imagenes"

El script:

  • Mantiene el original.
  • Si el ancho > 1200 px, crea una copia proporcional con sufijo .thumb en la misma carpeta.
  • No re-procesa si la .thumb ya está al día.
  • Respeta la orientación EXIF.

4) Usarlo en tu HTML/CSS

Carga las miniaturas en la galería y enlaza al original si quieres lightbox:

<section id="galeria">
  <a href="bosque1.jpg"><img src="bosque1.thumb.jpg" alt="Bosque 1"></a>
  <a href="bosque2.jpg"><img src="bosque2.thumb.jpg" alt="Bosque 2"></a>
  <!-- ... -->
</section>

CSS móvil first (básico):

#galeria img{
  width: 100%;
  aspect-ratio: 1/1;
  object-fit: cover;
  border-radius: 6px;
  display: block;
  margin-bottom: 10px;
}

5) Trucos útiles

  • Procesar subcarpetas (bash):
find /ruta/imagenes -type d -maxdepth 1 -print0 | xargs -0 -I{} python3 resize_thumb.py --folder "{}"
  • Ignorar ya generadas: el script lo hace por fecha (mtime).
  • Formatos: JPG/PNG/WEBP/TIFF soportados.

6) Problemas típicos

  • “No crea nada”: revisa que las imágenes superen THUMB_THRESHOLD.
  • “No cambia el tamaño”: la .thumb existe y es más reciente que el original.
  • “Colores raros en PNG”: prueba WEBP si tu web lo soporta, o baja quality en JPEG.

También te puede interesar