Spaces:
Runtime error
Runtime error
| """ | |
| Utilidades de validación y preprocesamiento de imágenes. | |
| Flujo de defensa: | |
| 1. validar_archivo: extensión, tipo MIME, tamaño mínimo | |
| 2. validar_imagen: integridad PIL, dimensiones 32-4000px | |
| 3. preprocess_image: resize 224x224 + normalización ImageNet | |
| Cada función retorna (bool, mensaje) para manejo de errores consistente. | |
| """ | |
| import os | |
| import numpy as np | |
| from PIL import Image, UnidentifiedImageError | |
| from app.config import ALLOWED_EXTENSIONS, ALLOWED_MIMES, IMG_MIN_SIZE, IMG_MAX_SIZE, MIN_FILE_SIZE | |
| def validar_archivo(nombre: str, content_type: str, tamaño: int = -1) -> tuple[bool, str]: | |
| ext = os.path.splitext(nombre)[1].lower() | |
| if ext not in ALLOWED_EXTENSIONS: | |
| return False, f"Formato no soportado: {ext}. Usa: {', '.join(ALLOWED_EXTENSIONS)}" | |
| if content_type and content_type not in ALLOWED_MIMES: | |
| return False, f"Tipo MIME no válido: {content_type}" | |
| if tamaño >= 0 and tamaño < MIN_FILE_SIZE: | |
| return False, "La imagen es demasiado pequeña o está vacía" | |
| return True, "" | |
| def validar_imagen(ruta: str) -> tuple[bool, str]: | |
| try: | |
| with Image.open(ruta) as img: | |
| img.verify() | |
| with Image.open(ruta) as img: | |
| img.load() | |
| w, h = img.size | |
| except (UnidentifiedImageError, Exception): | |
| return False, "La imagen está corrupta o no es válida" | |
| if w < IMG_MIN_SIZE or h < IMG_MIN_SIZE: | |
| return False, f"La imagen es muy pequeña ({w}x{h}). Mínimo: {IMG_MIN_SIZE}px" | |
| if w > IMG_MAX_SIZE or h > IMG_MAX_SIZE: | |
| return False, f"La imagen es muy grande ({w}x{h}). Máximo: {IMG_MAX_SIZE}px" | |
| return True, "" | |
| def preprocess_image(ruta: str) -> np.ndarray: | |
| """ | |
| Preprocesa imagen para ONNX inference sin torch/torchvision. | |
| Resize 224x224 + normalizacion ImageNet usando PIL + numpy. | |
| """ | |
| from PIL import Image | |
| img = Image.open(ruta).convert('RGB') | |
| img = img.resize((224, 224), Image.BILINEAR) | |
| arr = np.array(img, dtype=np.float32) / 255.0 | |
| mean = np.array([0.485, 0.456, 0.406], dtype=np.float32) | |
| std = np.array([0.229, 0.224, 0.225], dtype=np.float32) | |
| arr = (arr - mean) / std | |
| arr = arr.transpose(2, 0, 1) | |
| arr = np.expand_dims(arr, axis=0) | |
| return arr | |