Files
comic-manager/processors/image_normalizer.py
T

69 lines
2.0 KiB
Python

# processors/image_normalizer.py
import os
from core.constants import IMAGE_EXTENSIONS
from core.result import StepResult
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)