GPT-6 Sol & Claude Opus 5.5 sind daGPT-6 Sol zum halben Preis von 5.6 Sol

Nano Banana Pro API: Python-Tutorial, Bildbearbeitung und Preis

Ein POST, ein Poll, ein Download: ein Nano-Banana-Pro-Skript, das läuft.

Kiki, OmniaKey COO9 Min. Lesezeit
Auf dieser Seite

Nano Banana Pro ist Googles gemini-3-pro-image, und in OmniaKey rufst du es mit einem einzigen POST /v1/media/tasks auf. Unsere drei Tests im Format 3:4 kamen mit 896x1200, 1792x2400 und 3584x4800 zurück, und jedes Wort auf dem Poster war richtig geschrieben.

Kurze Antwort

  • Modell: gemini-3-pro-image ist Googles GA-Modell-ID. Die Vertex-Modellkarte nennt als Veröffentlichungsdatum den 28. Mai 2026.
  • Aufruf: Schicke POST https://api.omniakey.com/v1/media/tasks mit einem Idempotency-Key, frage GET /v1/media/tasks/{id} ab, bis der Status succeeded ist, und lade dann assets[0].url herunter.
  • Parameter: parameters.aspect_ratio und parameters.image_size; die Größenwerte sind 1K, 2K und 4K, mit großem K.
  • Limit pro Anfrage: 1 MiB für den ganzen Body, inklusive der Base64-Bilddaten darin.
  • Googles Preis: $0.134 pro 1K/2K-Bild und $0.24 pro 4K-Bild, von der Preisseite der Gemini-API.
  • Unsere Token-Zahlen: Die drei Aufgaben meldeten 1,133, 1,225 und 2,480 Ausgabe-Token. Bei $120 pro Million Bild-Token sind das $0.136, $0.147 und $0.298.
  • Bearbeiten: Nutze operation: "edit" und lege das Ausgangsbild in input.image als {data, mime_type} ab.

Die Modellseite von Nano Banana Pro bei OmniaKey nimmt auch gemini-3-pro-image-preview an, die ältere Snapshot-ID, zum gleichen Preis.

Modell-ID und was du brauchst

In deinen Code gehört gemini-3-pro-image. Googles Vertex-Modellkarte führt es mit Launch-Phase GA und dem Datum 28. Mai 2026. Unterstützt werden Ausgaben in 1K, 2K und 4K.

Die -preview-ID zeigt auf dasselbe Modell. Die Tabelle der Bildmodelle bei OmniaKey beschreibt gemini-3-pro-image-preview als "Same model, -preview snapshot id", zum gleichen Preis pro Aufruf.

Du brauchst zwei Dinge:

  1. Einen OmniaKey-API-Key, exportiert, damit das Skript ihn lesen kann: export OMNIAKEY_API_KEY="your-key".
  2. Python 3. Das Skript unten nutzt nur die Standardbibliothek: urllib, json, time, uuid, base64 und pathlib. Es ist kein SDK zu installieren.

Das Python-Skript

Drei Schritte: Aufgabe anlegen, abfragen, Bild herunterladen. Speichere das Ganze als nano_banana.py und starte es mit python3 nano_banana.py.

python
import base64
import json
import os
import time
import urllib.request
import uuid
from pathlib import Path

API = "https://api.omniakey.com/v1/media/tasks"
HEADERS = {
    "Authorization": f"Bearer {os.environ['OMNIAKEY_API_KEY']}",
    "Content-Type": "application/json",
}


def call(url, payload=None, headers=None, method=None):
    body = json.dumps(payload).encode() if payload is not None else None
    req = urllib.request.Request(url, data=body, headers=headers or HEADERS, method=method)
    with urllib.request.urlopen(req, timeout=60) as resp:
        return resp.status, json.loads(resp.read())


def create_task(prompt, aspect_ratio="3:4", image_size="2K", image_path=None):
    body = {
        "model": "gemini-3-pro-image",
        "type": "image",
        "operation": "generate" if image_path is None else "edit",
        "input": {"prompt": prompt},
        "parameters": {"aspect_ratio": aspect_ratio, "image_size": image_size},
    }
    if image_path:
        encoded = base64.b64encode(Path(image_path).read_bytes()).decode("utf-8")
        body["input"]["image"] = {"data": encoded, "mime_type": "image/png"}
    headers = {**HEADERS, "Idempotency-Key": str(uuid.uuid4())}
    status, task = call(API, body, headers, "POST")
    print("created", task["id"], "HTTP", status)
    return task


def wait(task_id, interval=3, timeout=300):
    deadline = time.time() + timeout
    while time.time() < deadline:
        _, task = call(f"{API}/{task_id}")
        print(task["status"], task["progress"]["percent"])
        if task["status"] in ("succeeded", "failed", "canceled"):
            return task
        time.sleep(interval)
    # A timeout is not a failure: keep the task id and poll it again.
    raise TimeoutError(f"task {task_id} is still running")


def download(task, out_path):
    asset = task["assets"][0]
    with urllib.request.urlopen(asset["url"], timeout=120) as resp:
        Path(out_path).write_bytes(resp.read())
    print("saved", out_path, asset["mime_type"], asset["byte_size"], "bytes")


if __name__ == "__main__":
    task = create_task(
        "A vintage travel poster for the Night Train from Zürich to Milano, "
        "departing 21:40 from platform 7. A steam train crosses a stone arch "
        "bridge below snowy mountains under a deep blue night sky, with a cream "
        "border. Spell every word exactly as written.",
        aspect_ratio="3:4",
        image_size="2K",
    )
    task = wait(task["id"])
    if task["status"] != "succeeded":
        raise SystemExit(f"{task['status']}: {task.get('error')}")
    download(task, "night-train.jpg")

image_size akzeptiert 1K, 2K oder 4K. Googles Bildleitfaden ist eindeutig: "You must use an uppercase 'K' … Lowercase parameters (e.g., 1k) will be rejected." Schicke 2K, nicht 2k.

Idempotency-Key ist Pflicht. Ein frisches UUID pro Anfrage ist die einfache Regel; verwende einen Key nur wieder, wenn du genau denselben Body erneut sendest. OmniaKey gibt dann die ursprüngliche Aufgabe mit HTTP 200 zurück, statt doppelt abzurechnen, und antwortet mit 409, wenn derselbe Key mit einem anderen Body ankommt.

Der Aufruf zum Anlegen liefert 202 mit einer id. Die Doku zu Media-Tasks bei OmniaKey beschreibt den ganzen Ablauf; die fertige Aufgabe trägt diese Felder:

json
{
  "id": "task_AbMRVqzSnVh0VwBj0S7NuMUxy5sZtfHP",
  "status": "succeeded",
  "progress": {"percent": 100, "stage": "completed"},
  "usage": {"total_tokens": 1133},
  "assets": [
    {
      "kind": "image",
      "mime_type": "…",
      "url": "https://…signed-url…"
    }
  ]
}

Lies assets[0].url und lade sofort herunter: Der signierte Link gilt etwa eine Stunde, der Task-Datensatz bleibt 24 Stunden. Das Feld mime_type nennt das Format; Gemini-Modelle liefern meist JPEG.

Dasselbe Skript mit 1:1 und 2K und einem chinesischen Schild als Prompt lieferte das:

Ein dunkles Metallschild an einer Ziegelwand mit drei Zeilen chinesischem Text und einer Telefonnummer
2K, 1:1: 2048x2048 in 47.2 s. Alle drei chinesischen Zeilen und 010-6789 4321 kamen korrekt zurück; Rost verdeckt einen Teil der ersten 0.

Ein vorhandenes Bild bearbeiten

Setze operation: "edit" und übergib das Ausgangsbild in input.image als {data, mime_type}. Das Skript oben macht das schon, sobald du ihm einen image_path gibst:

python
task = create_task(
    "Hang this poster in a thin black frame on a warm white wall, with a brass "
    "picture light above it, a low wooden cabinet below and a trailing plant on "
    "the right. Keep the poster exactly as it is.",
    aspect_ratio="1:1",
    image_size="2K",
    image_path="night-train-2k.png",
)

Der Body, der dabei rausgeht, sieht so aus:

json
{
  "model": "gemini-3-pro-image",
  "type": "image",
  "operation": "edit",
  "input": {
    "prompt": "Hang this poster in a thin black frame on a warm white wall…",
    "image": {"data": "…base64…", "mime_type": "image/png"}
  },
  "parameters": {"aspect_ratio": "1:1", "image_size": "2K"}
}

Die Vorlage im Beispiel ist ein PNG, deshalb schreibt das Skript image/png; bei einem JPEG änderst du dieses Label. Für mehrere Vorlagen nutzt du input.images und gibst jedem Eintrag dieselbe Form {data, mime_type}. Googles Leitfaden nennt 14 Referenzbilder als Obergrenze; bei gemini-3-pro-image verteilt sich das auf 6 Objektbilder, 5 Charakterbilder und 3 Stilreferenzen.

Halte den Body unter 1 MiB. Base64 macht die Datei etwa ein Drittel größer, also verkleinere oder komprimiere die Vorlage vor dem Kodieren. Unsere Bearbeitung nutzte das 2K-Poster und behielt jedes Wort und das Layout:

Das Nachtzug-Poster in einem schwarzen Rahmen an einer Wand, mit Bildlampe darüber und einer Pflanze rechts
2K, Bearbeitung 1:1: 2048x2048 in 49.9 s. Text und Design des Posters blieben erhalten; der Rahmen ist ein sauberes Rechteck.

1K, 2K und 4K: was jedes Format bringt

Wir haben denselben 3:4-Prompt in allen drei Größen laufen lassen. Die Pixelmaße passten exakt zu Googles Tabelle für 3:4: 896x1200 bei 1K, 1792x2400 bei 2K und 3584x4800 bei 4K. Der Postertext war in jeder Größe korrekt.

Das Nachtzug-Poster in 1K: Dampfzug auf einer Steinbrücke, verschneite Berge und ein tiefblauer Himmel
1K, 3:4: 896x1200 in 28.4 s. Alle vier Posterzeilen stimmen; Lampen und Treibstangen der Lokomotive drängen sich.
Dasselbe Nachtzug-Poster in 2K, mit einem Dorf und zwei Kirchtürmen am rechten Hang
2K, 3:4: 1792x2400 in 48.2 s. Gleicher Text, dazu ein Dorf und zwei Türmchen am rechten Hang.
Dasselbe Nachtzug-Poster in 4K, mit drei Wagen und Tender hinter der Lokomotive
4K, 3:4: 3584x4800 in 66.9 s. Drei Wagen und der Tender sind gezeichnet; die Ziegelfugen fallen unterschiedlich dick aus.

Mit der Größe ändert sich das Detail, nicht die Rechtschreibung:

  • 1K: Die Zugfront ist gedrängt: Lampen, Räder und Treibstangen sitzen dicht beieinander.
  • 2K: Am rechten Hang erscheinen das Dorf und seine zwei Türmchen, der Schornstein bekommt einen blassen Rauchfaden, die Brücke zeigt sieben Bögen.
  • 4K: Die drei Wagen und der Tender sind getrennt, und das Mauerwerk zeigt Fugen unterschiedlicher Dicke. Die Mechanik unter der Lokomotive bleibt vereinfacht.

Die Zeit wuchs mit der Größe: 28.4 s, 48.2 s und 66.9 s. Jede Größe lief einmal, lies diese Sekunden also als einen einzelnen Durchlauf.

Google rechnet Bildausgabe mit $120 pro Million Token ab, und seine Tabelle nennt 1,120 Token für 1K und 2K sowie 2,000 Token für 4K. Daraus folgt Googles eigene Schätzung:

text
1,120 × $120 ÷ 1,000,000 = $0.134 per 1K image
1,120 × $120 ÷ 1,000,000 = $0.134 per 2K image
2,000 × $120 ÷ 1,000,000 = $0.24  per 4K image

Unsere Aufgaben meldeten mehr Token als Googles Beispiele. Hier dieselbe Rechnung mit unseren Zahlen:

text
1,133 × $120 ÷ 1,000,000 = $0.136 per 1K image
1,225 × $120 ÷ 1,000,000 = $0.147 per 2K image
2,480 × $120 ÷ 1,000,000 = $0.298 per 4K image
GrößePixel, 3:4Unsere ZeitUnsere TokenGoogles Schätzung
1K896x120028.4 s1,133$0.134
2K1792x240048.2 s1,225$0.134
4K3584x480066.9 s2,480$0.24

OmniaKey rechnet einen Bildaufruf pauschal ab, nicht nach Token, deshalb bewegt sich der Betrag nicht mit diesen Zahlen; die aktuelle Rate pro Aufruf steht auf der Modellseite, und eine fehlgeschlagene Aufgabe wird erstattet. Googles Schätzung nach Token-Rate liegt für dieselben drei Bilder bei $0.134, $0.134 und $0.24.

Fehler, die dir begegnen

Die Fehlschläge hier laufen fast immer auf einen Feldnamen oder eine Dateigröße hinaus, nicht aufs Modell. Diese listet die Media-Doku von OmniaKey für diesen Endpunkt:

HTTPCode oder StatusWas er bedeutetWas zu tun ist
400invalid_requestFehlerhafter Body, nicht unterstützte Operation oder falscher ParameterJSON und die Feldnamen unten prüfen
503no_available_channelKein Kanal bedient dieses Modell geradeModell wechseln; erneutes Senden hilft nicht
—failedDie Aufgabe endete ohne Ergebniserror.code und error.message lesen

Eine fehlgeschlagene Aufgabe ist kein HTTP-Fehler: Der Aufruf zum Anlegen war erfolgreich, also fragst du die Aufgabe ab und liest ihr error-Objekt. Fehlgeschlagene und abgebrochene Aufgaben werden automatisch erstattet.

Eine Vorlage in voller Auflösung als Base64 kann den Body über 1 MiB schieben. Verkleinere zuerst und prüfe die kodierte Länge, nicht nur die Dateigröße.

Googles Leitfaden lehnt ein kleines 1k ab. Nutze 1K, 2K oder 4K.

Die Bild-Doku von OmniaKey lehnt bei Gemini-Modellen außerdem size und ein mime_type auf oberster Ebene ab, weil das keine Gemini-Parameter sind. Nutze stattdessen parameters.aspect_ratio und parameters.image_size und lies das Ausgabeformat aus dem Feld mime_type der Antwort.

Häufige Fragen

Welche Modell-ID hat die Nano Banana Pro API?

gemini-3-pro-image. Googles Vertex-Modellkarte führt es als GA mit Veröffentlichungsdatum 28. Mai 2026, und OmniaKey nimmt dieselbe ID an. Die ältere ID gemini-3-pro-image-preview funktioniert bei OmniaKey weiter und zeigt auf dasselbe Modell.

Was kostet ein Bild mit Nano Banana Pro?

Google schätzt $0.134 für ein 1K- oder 2K-Bild und $0.24 für ein 4K-Bild, bei $120 pro Million Bild-Token. Unsere Aufgaben meldeten 1,133, 1,225 und 2,480 Token, das sind zu dieser Rate $0.136, $0.147 und $0.298. OmniaKey nennt auf der Modellseite seine eigene Rate pro Aufruf.

Kann Nano Banana Pro chinesischen Text zeichnen?

Ja. Unser 2K-Schild kam mit drei korrekten chinesischen Zeilen zurück — 同福客栈, 住宿 餐饮 茶水 und 010-6789 4321 — samt aller 11 Ziffern und dem Bindestrich.

Soll ich 1K, 2K oder 4K anfordern?

Für ein Poster wie unseres ist 2K die brauchbare Mitte. Alle drei Größen schrieben unser Poster richtig, 4K kauft also feinere Details — getrennte Wagen, sichtbare Ziegelfugen — statt besserem Text. Für Entwürfe, bei denen 896x1200 reicht, nimm 1K.

Warum kam meine Bearbeitung mit 400 invalid_request zurück?

Die üblichen Ursachen sind ein Body über 1 MiB, die Vorlage im falschen Feld oder ein Gemini-Modell, das size oder ein mime_type auf oberster Ebene bekommt. Lege das Bild in input.image als {data, mime_type} ab, halte den kodierten Body unter 1 MiB und nutze aspect_ratio und image_size.

Geprüfte Quellen

Änderungsverlauf

  • 2026-11-03: Erste Fassung; fünf Testaufrufe an dem Tag über OmniaKey.

Modelle in diesem Artikel

Nano Banana ProGemini BildBild-APIPythonAPI-Tutorial

Verwandte Artikel

Neueste Beiträge

Beliebte Anleitungen