feat: Imagen Image-to-Image — Referenzbild als rawBytes übergeben
- _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
This commit is contained in:
+22
-6
@@ -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;}</style></head>
|
||||
|
||||
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;}</style></head>
|
||||
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;}</style></head>
|
||||
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;}</style></head>
|
||||
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)
|
||||
|
||||
Reference in New Issue
Block a user