From 23a4bff25434a7ab76b331b2e16661991556e35d Mon Sep 17 00:00:00 2001 From: Hermes Agent Date: Tue, 23 Jun 2026 08:30:48 +0200 Subject: [PATCH] =?UTF-8?q?feat:=20Imagen=20Image-to-Image=20=E2=80=94=20R?= =?UTF-8?q?eferenzbild=20als=20rawBytes=20=C3=BCbergeben?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - _imagen_generate akzeptiert image_base64 (str|None) - Multipart-Parser extrahiert hochgeladenes Bild als Base64 - rawBytes im Instance-Feld für Image-to-Image-Modus - Duplicate import base64 as b64 entfernt - Getestet: Text-to-Image + Image-to-Image funktionieren --- article_server.py | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/article_server.py b/article_server.py index ced6e75..e27b876 100644 --- a/article_server.py +++ b/article_server.py @@ -95,21 +95,32 @@ def _get_imagen_key() -> str: def _imagen_generate( prompt: str, - image_urls: list, + image_base64: str | None, aspect_ratio: str, resolution: str ) -> dict: - """Google Imagen aufrufen — synchron, liefert Base64-Bild direkt zurück.""" + """Google Imagen aufrufen — synchron, liefert Base64-Bild direkt zurück. + + Args: + prompt: Text-Prompt für die Bildgenerierung. + image_base64: Optionales Referenzbild als Base64 (Image-to-Image). + aspect_ratio: Seitenverhältnis (z.B. "16:9"). + resolution: Auflösung ("1K", "2K", "4K"). + """ key = _get_imagen_key() if not key: return {"error": "Kein Google Imagen API-Key"} + instance = {"prompt": prompt} + if image_base64: + instance["rawBytes"] = image_base64 + body = json.dumps({ - "instances": [{"prompt": prompt}], + "instances": [instance], "parameters": { "sampleCount": 1, "aspectRatio": aspect_ratio, - "sampleImageSize": IMAGEN_SIZE_MAP.get(resolution, "2048x2048"), + "sampleImageSize": IMAGEN_SIZE_MAP.get(resolution, "2K"), } }).encode() @@ -975,6 +986,8 @@ h1{color:#c0392b;}p{color:#888;} def _handle_image_generate(self): """Bildgenerierung via Google Imagen (synchron, Base64→JPEG).""" + import base64 as b64 + content_type = self.headers.get("Content-Type", "") if "multipart/form-data" not in content_type: self._json_reply(400, {"ok": False, "error": "Expected multipart/form-data"}) @@ -993,6 +1006,7 @@ h1{color:#c0392b;}p{color:#888;} prompt = "" aspect_ratio = "16:9" resolution = "1K" + image_base64 = None for part in parts: if b"Content-Disposition" not in part: @@ -1009,13 +1023,16 @@ h1{color:#c0392b;}p{color:#888;} aspect_ratio = content.decode("utf-8", errors="ignore") elif 'name="resolution"' in headers_raw: resolution = content.decode("utf-8", errors="ignore") + elif 'name="image"' in headers_raw and len(content) > 100: + # Referenzbild als Base64 für Image-to-Image + image_base64 = b64.b64encode(content).decode() if not prompt: self._json_reply(400, {"ok": False, "error": "Prompt fehlt"}) return # Google Imagen aufrufen (synchron!) - result = _imagen_generate(prompt, [], aspect_ratio, resolution) + result = _imagen_generate(prompt, image_base64, aspect_ratio, resolution) if "error" in result: self._json_reply(500, {"ok": False, "error": result["error"]}) return @@ -1031,7 +1048,6 @@ h1{color:#c0392b;}p{color:#888;} self._json_reply(500, {"ok": False, "error": "Leeres Base64-Bild"}) return - import base64 as b64 img_bytes = b64.b64decode(b64_data) # Im media-Ordner speichern (wie normale Uploads)