From 3711ce202f97cd1b674de1bebc43c25c6a537514 Mon Sep 17 00:00:00 2001 From: Bruno Charest Date: Thu, 25 Jun 2026 22:41:08 -0400 Subject: [PATCH] Resize images to max 1024px before AI analysis to prevent timeouts Large images (10MB+ PNG) create huge base64 payloads that cause OpenRouter/Gemini API timeouts. Now resized to 1024px JPEG quality 85 before sending, reducing payload from ~15MB to ~100KB. --- app/services/ai_vision.py | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/app/services/ai_vision.py b/app/services/ai_vision.py index 625a3c2..16069b8 100644 --- a/app/services/ai_vision.py +++ b/app/services/ai_vision.py @@ -40,15 +40,40 @@ def _get_client() -> genai.Client: async def _read_image(file_path: str) -> tuple[bytes, str]: + """Lit l'image via le StorageBackend et la redimensionne pour l'AI (max 1024px).""" path = Path(file_path) suffix = path.suffix.lower() + backend = get_storage_backend() + data = await backend.get_bytes(file_path) + + # Redimensionner pour éviter les timeouts AI sur les grandes images + try: + from PIL import Image as PILImage + import io as pil_io + original_size = len(data) + img = PILImage.open(pil_io.BytesIO(data)) + max_dim = 1024 + if img.width > max_dim or img.height > max_dim: + img.thumbnail((max_dim, max_dim), PILImage.Resampling.LANCZOS) + buf = pil_io.BytesIO() + if img.mode in ("RGBA", "P"): + img = img.convert("RGB") + img.save(buf, format="JPEG", quality=85) + data = buf.getvalue() + logger.info("ai.image_resized", extra={ + "file": path.name, + "original_bytes": original_size, + "resized_bytes": len(data), + }) + return data, "image/jpeg" + except Exception: + pass # Si Pillow échoue, on utilise l'image originale + mime_map = { ".jpg": "image/jpeg", ".jpeg": "image/jpeg", ".png": "image/png", ".gif": "image/gif", ".webp": "image/webp", } media_type = mime_map.get(suffix, "image/jpeg") - backend = get_storage_backend() - data = await backend.get_bytes(file_path) return data, media_type