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(
|
def _imagen_generate(
|
||||||
prompt: str,
|
prompt: str,
|
||||||
image_urls: list,
|
image_base64: str | None,
|
||||||
aspect_ratio: str,
|
aspect_ratio: str,
|
||||||
resolution: str
|
resolution: str
|
||||||
) -> dict:
|
) -> 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()
|
key = _get_imagen_key()
|
||||||
if not key:
|
if not key:
|
||||||
return {"error": "Kein Google Imagen API-Key"}
|
return {"error": "Kein Google Imagen API-Key"}
|
||||||
|
|
||||||
|
instance = {"prompt": prompt}
|
||||||
|
if image_base64:
|
||||||
|
instance["rawBytes"] = image_base64
|
||||||
|
|
||||||
body = json.dumps({
|
body = json.dumps({
|
||||||
"instances": [{"prompt": prompt}],
|
"instances": [instance],
|
||||||
"parameters": {
|
"parameters": {
|
||||||
"sampleCount": 1,
|
"sampleCount": 1,
|
||||||
"aspectRatio": aspect_ratio,
|
"aspectRatio": aspect_ratio,
|
||||||
"sampleImageSize": IMAGEN_SIZE_MAP.get(resolution, "2048x2048"),
|
"sampleImageSize": IMAGEN_SIZE_MAP.get(resolution, "2K"),
|
||||||
}
|
}
|
||||||
}).encode()
|
}).encode()
|
||||||
|
|
||||||
@@ -975,6 +986,8 @@ h1{color:#c0392b;}p{color:#888;}</style></head>
|
|||||||
|
|
||||||
def _handle_image_generate(self):
|
def _handle_image_generate(self):
|
||||||
"""Bildgenerierung via Google Imagen (synchron, Base64→JPEG)."""
|
"""Bildgenerierung via Google Imagen (synchron, Base64→JPEG)."""
|
||||||
|
import base64 as b64
|
||||||
|
|
||||||
content_type = self.headers.get("Content-Type", "")
|
content_type = self.headers.get("Content-Type", "")
|
||||||
if "multipart/form-data" not in content_type:
|
if "multipart/form-data" not in content_type:
|
||||||
self._json_reply(400, {"ok": False, "error": "Expected multipart/form-data"})
|
self._json_reply(400, {"ok": False, "error": "Expected multipart/form-data"})
|
||||||
@@ -993,6 +1006,7 @@ h1{color:#c0392b;}p{color:#888;}</style></head>
|
|||||||
prompt = ""
|
prompt = ""
|
||||||
aspect_ratio = "16:9"
|
aspect_ratio = "16:9"
|
||||||
resolution = "1K"
|
resolution = "1K"
|
||||||
|
image_base64 = None
|
||||||
|
|
||||||
for part in parts:
|
for part in parts:
|
||||||
if b"Content-Disposition" not in part:
|
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")
|
aspect_ratio = content.decode("utf-8", errors="ignore")
|
||||||
elif 'name="resolution"' in headers_raw:
|
elif 'name="resolution"' in headers_raw:
|
||||||
resolution = content.decode("utf-8", errors="ignore")
|
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:
|
if not prompt:
|
||||||
self._json_reply(400, {"ok": False, "error": "Prompt fehlt"})
|
self._json_reply(400, {"ok": False, "error": "Prompt fehlt"})
|
||||||
return
|
return
|
||||||
|
|
||||||
# Google Imagen aufrufen (synchron!)
|
# Google Imagen aufrufen (synchron!)
|
||||||
result = _imagen_generate(prompt, [], aspect_ratio, resolution)
|
result = _imagen_generate(prompt, image_base64, aspect_ratio, resolution)
|
||||||
if "error" in result:
|
if "error" in result:
|
||||||
self._json_reply(500, {"ok": False, "error": result["error"]})
|
self._json_reply(500, {"ok": False, "error": result["error"]})
|
||||||
return
|
return
|
||||||
@@ -1031,7 +1048,6 @@ h1{color:#c0392b;}p{color:#888;}</style></head>
|
|||||||
self._json_reply(500, {"ok": False, "error": "Leeres Base64-Bild"})
|
self._json_reply(500, {"ok": False, "error": "Leeres Base64-Bild"})
|
||||||
return
|
return
|
||||||
|
|
||||||
import base64 as b64
|
|
||||||
img_bytes = b64.b64decode(b64_data)
|
img_bytes = b64.b64decode(b64_data)
|
||||||
|
|
||||||
# Im media-Ordner speichern (wie normale Uploads)
|
# Im media-Ordner speichern (wie normale Uploads)
|
||||||
|
|||||||
Reference in New Issue
Block a user