90 lines
2.7 KiB
Python
90 lines
2.7 KiB
Python
# processors/image_normalizer.py
|
|
|
|
import os
|
|
|
|
from core.constants import IMAGE_EXTENSIONS
|
|
from core.result import StepResult
|
|
|
|
|
|
def preview_normalize_images(work_dir: str, target_ext: str) -> list[tuple[str, str]]:
|
|
"""Devuelve lista de (nombre_actual, nombre_final) sin convertir nada."""
|
|
target_ext = target_ext.lower()
|
|
if not target_ext.startswith("."):
|
|
target_ext = "." + target_ext
|
|
|
|
result = []
|
|
for root, _, files in os.walk(work_dir):
|
|
for f in files:
|
|
ext = os.path.splitext(f)[1].lower()
|
|
normalized_ext = ".jpg" if ext == ".jpeg" else ext
|
|
if ext not in IMAGE_EXTENSIONS:
|
|
continue
|
|
if normalized_ext == target_ext:
|
|
continue
|
|
stem = os.path.splitext(f)[0]
|
|
result.append((f, stem + target_ext))
|
|
|
|
return result
|
|
|
|
|
|
def normalize_images(work_dir: str, target_ext: str = ".jpg") -> StepResult:
|
|
"""
|
|
Convierte todas las imágenes al formato indicado por target_ext.
|
|
Requiere Pillow. Si no está instalado, devuelve un StepResult con error.
|
|
"""
|
|
try:
|
|
from PIL import Image
|
|
except ImportError:
|
|
return StepResult(
|
|
step="normalize_images",
|
|
changed=False,
|
|
errors=["Pillow no instalado. Ejecuta: pip install Pillow"],
|
|
)
|
|
|
|
target_ext = target_ext.lower()
|
|
if not target_ext.startswith("."):
|
|
target_ext = "." + target_ext
|
|
|
|
# Mapa de extensión a formato PIL
|
|
FORMAT_MAP = {
|
|
".jpg": "JPEG",
|
|
".jpeg": "JPEG",
|
|
".png": "PNG",
|
|
".webp": "WEBP",
|
|
}
|
|
pil_format = FORMAT_MAP.get(target_ext)
|
|
if pil_format is None:
|
|
return StepResult(
|
|
step="normalize_images",
|
|
changed=False,
|
|
errors=[f"Formato de imagen no soportado: {target_ext}"],
|
|
)
|
|
|
|
changed = False
|
|
details = []
|
|
|
|
for root, _, files in os.walk(work_dir):
|
|
for f in files:
|
|
ext = os.path.splitext(f)[1].lower()
|
|
normalized_ext = ".jpg" if ext == ".jpeg" else ext
|
|
if ext not in IMAGE_EXTENSIONS:
|
|
continue
|
|
if normalized_ext == target_ext:
|
|
continue
|
|
|
|
src = os.path.join(root, f)
|
|
stem = os.path.splitext(f)[0]
|
|
dst = os.path.join(root, stem + target_ext)
|
|
|
|
with Image.open(src) as img:
|
|
# Convertir modos incompatibles con JPEG
|
|
if pil_format == "JPEG" and img.mode in ("RGBA", "P", "LA"):
|
|
img = img.convert("RGB")
|
|
img.save(dst, format=pil_format)
|
|
|
|
os.remove(src)
|
|
details.append(f"{f} → {stem + target_ext}")
|
|
changed = True
|
|
|
|
return StepResult(step="normalize_images", changed=changed, details=details)
|