diff --git a/bridge/aria_bridge.py b/bridge/aria_bridge.py index 0a5999f..f2c10ec 100644 --- a/bridge/aria_bridge.py +++ b/bridge/aria_bridge.py @@ -1486,6 +1486,31 @@ class ARIABridge: size_kb = len(file_b64) // 1365 logger.info("[rvs] Datei gespeichert: %s (%dKB)", file_path, size_kb) + # Pixel-Bilder fuer Claude-Vision shrinken wenn > 2 MB. SVG/PDF/ZIP + # bleiben unangetastet (Vision laeuft eh nur auf Raster-Formaten). + CLAUDE_VISION_FORMATS = ("image/jpeg", "image/jpg", "image/png", "image/webp", "image/gif") + if file_type.lower() in CLAUDE_VISION_FORMATS: + file_size_bytes = os.path.getsize(file_path) + if file_size_bytes > 2 * 1024 * 1024: + try: + from PIL import Image + with Image.open(file_path) as img: + orig_w, orig_h = img.size + # Anthropic-Empfehlung: max 1568px lange Seite. RGB-Konvertierung + # falls RGBA/Palette (JPEG braucht RGB). + img.thumbnail((1568, 1568), Image.Resampling.LANCZOS) + if img.mode in ("RGBA", "P"): + img = img.convert("RGB") + img.save(file_path, "JPEG", quality=85, optimize=True) + new_size_bytes = os.path.getsize(file_path) + logger.info("[rvs] Bild verkleinert: %dx%d → %dx%d, %.1fMB → %.1fMB", + orig_w, orig_h, img.size[0], img.size[1], + file_size_bytes / 1024 / 1024, + new_size_bytes / 1024 / 1024) + except Exception as e: + logger.warning("[rvs] Bild-Resize fehlgeschlagen (%s) — Original wird genutzt: %s", + file_name, e) + # In Pending-Queue + Flush-Timer (anti-spam Buffering) self._pending_files.append((file_path, file_name, file_type, size_kb, int(width or 0), int(height or 0))) if self._pending_files_flush_task and not self._pending_files_flush_task.done(): diff --git a/bridge/requirements.txt b/bridge/requirements.txt index 71587bb..bee9b3e 100644 --- a/bridge/requirements.txt +++ b/bridge/requirements.txt @@ -16,3 +16,6 @@ sounddevice # Wake-Word Erkennung openwakeword + +# Bild-Resizing (zu grosse Pixel-Bilder shrinken bevor Claude-Vision sie sieht — 5MB-Limit) +Pillow