Tutorial
Bilder mit der API freistellen: promptbasierte Bearbeitung
So ersetzen oder entfernen Sie Bildhintergründe mit Image-to-Image-Modellen auf hiapi – mit minimalem Code, Stapelverarbeitung und den Schema-Details, die die Produktfotografie exakt machen.
Herkömmliche Werkzeuge zur Hintergrundentfernung bieten nur eine Operation: das Motiv ausschneiden und einen transparenten Bereich (oder eine Volltonfarbe) zurücklassen. Promptbasierte Hintergrundentfernung mit Image-to-Image-Modellen liefert dagegen in einem einzigen Aufruf sowohl das Freistellungsergebnis als auch den ersetzten Hintergrund – einen nahtlosen weißen Studiohintergrund, eine Alltagsszene oder eine reine Markenfarbe –, weil das Modell den Hintergrund pixelweise um das erhaltene Motiv herum neu generiert, statt nur eine Alpha-Maske zu berechnen.
Diese Anleitung zeigt genau, wie Sie das auf hiapi umsetzen: welche Image-to-Image-Modelle bei der Hintergrundentfernung wirklich stark sind, die Request-/Response-Struktur, an der Sie sich beim Programmieren orientieren müssen, und die Produktionsmuster (Callbacks, Wiederholungen, Fehlerbehandlung), mit denen Stapeljobs verhindern, dass Ihr Produktkatalog stillschweigend verunreinigt wird.
Voraussetzungen:
- Ein hiapi-API-Schlüssel aus Ihrem Dashboard
- Python 3.9+ mit installiertem
requests(pip install requests) - Ihre Quellbilder werden unter einer öffentlichen URL gehostet – die hiapi-Task-API ruft Bilder per URL ab, nicht per Datei-Upload, daher funktionieren lokale Dateipfade nicht. Jeder Objektspeicher oder CDN eignet sich.
Wie Hintergrundentfernung als Image-to-Image-Task funktioniert
Jede Generierung auf hiapi – Bild, Video oder Audio – durchläuft denselben asynchronen Task-Lebenszyklus: Sie senden einen Task ab, erhalten eine taskId und rufen dann entweder die Ergebnisse ab (Polling) oder empfangen sie über eine Callback-URL. Die vollständige Vertragsbeschreibung finden Sie in der Referenz zur asynchronen Task-API; für die Hintergrundentfernung sind folgende Teile wichtig:
POST /v1/tasksmitmodel+input(Ihr Prompt, die Quellbild-URL und die Ausgabeform) gibt{"code":200,"data":{"taskId":"tk-hiapi-..."}}zurück. Zu diesem Zeitpunkt gibt es noch keinstatus-Feld.GET /v1/tasks/{taskId}gibtdata.statuszurück, mit einem der Wertequeued,handling,archiving,success,fail. Nursuccessundfailsind Endzustände.- Im Status
successistdata.outputein Array von{"url","type","expireAt"}. Dieurlist ein signierter, kurzlebiger Link (expireAtist ein Unix-Zeitstempel) – laden Sie ihn sofort herunter und speichern Sie nicht den Hotlink.
Verwenden Sie für das Modell den Image-to-Image-Endpunkt und lassen Sie den Prompt den ersetzten Hintergrund beschreiben, statt isoliert „Hintergrund entfernen“ zu sagen – diese Modelle reagieren weit besser auf konkrete Ziele als auf verneinende Anweisungen:
Remove the background completely and replace it with a seamless, pure white
studio background. Keep the subject's shape, edges, lighting, and colors
exactly unchanged. Do not add shadows, reflections, or any other objects
that were not in the original image.
Minimalbeispiel: ein Bild eingeben, Hintergrund ersetzen
seedream-5.0-lite/image-to-image ist die günstigste ausreichende Option für diesen Zweck – es akzeptiert prompt, image_urls, aspect_ratio und resolution (nur 2K oder 4K; dieser Endpunkt hat keine 1K-Stufe, und unbekannte Felder wie n oder seed werden direkt mit 400 abgelehnt).
import os
import time
import requests
API = "https://api.hiapi.ai/v1"
HEADERS = {
"Authorization": f"Bearer {os.environ['HIAPI_API_KEY']}",
"Content-Type": "application/json",
}
BACKGROUND_PROMPT = (
"Remove the background completely and replace it with a seamless, pure "
"white studio background. Keep the subject's shape, edges, lighting, and "
"colors exactly unchanged. Do not add shadows, reflections, or any other "
"objects that were not in the original image."
)
def create_task(model: str, task_input: dict) -> str:
resp = requests.post(f"{API}/tasks", headers=HEADERS,
json={"model": model, "input": task_input}, timeout=60)
resp.raise_for_status()
return resp.json()["data"]["taskId"]
def wait_task(task_id: str, timeout_s: int = 180, poll_s: int = 3) -> dict:
deadline = time.time() + timeout_s
while time.time() < deadline:
resp = requests.get(f"{API}/tasks/{task_id}", headers=HEADERS, timeout=30)
resp.raise_for_status()
task = resp.json()["data"]
if task["status"] == "success":
return task
if task["status"] == "fail":
err = task.get("error") or {}
raise RuntimeError(f"task {task_id} failed: {err.get('code')} {err.get('message')}")
time.sleep(poll_s)
raise TimeoutError(f"task {task_id} still {task['status']} after {timeout_s}s")
task_id = create_task("seedream-5.0-lite/image-to-image", {
"prompt": BACKGROUND_PROMPT,
"image_urls": ["https://your-cdn.example.com/product-photo.jpg"],
"aspect_ratio": "1:1",
"resolution": "2K",
})
task = wait_task(task_id)
image_bytes = requests.get(task["output"][0]["url"], timeout=60).content
with open("product-no-bg.png", "wb") as f:
f.write(image_bytes)
Das ist die gesamte Schleife: absenden, abfragen, herunterladen. Wenn Sie vor der Integration in eine Pipeline eine schnelle Validierung ohne Code wünschen, führt das AI Product Photo Lab dieselbe Art der Hintergrundersetzung im Browser aus.
Stapelverarbeitung eines Produktkatalogs
Echte Produktkataloge enthalten Dutzende oder Hunderte von Bildern, und die Task-API hat keinen nativen Stapel-Endpunkt – Sie müssen einzelne Task-Übermittlungen selbst aufteilen und sie parallel abfragen:
from concurrent.futures import ThreadPoolExecutor, as_completed
def remove_background(image_url: str, aspect_ratio: str = "1:1") -> str:
task_id = create_task("seedream-5.0-lite/image-to-image", {
"prompt": BACKGROUND_PROMPT,
"image_urls": [image_url],
"aspect_ratio": aspect_ratio,
"resolution": "2K",
})
task = wait_task(task_id)
return task["output"][0]["url"]
source_urls = [
"https://your-cdn.example.com/sku-1001.jpg",
"https://your-cdn.example.com/sku-1002.jpg",
# ...
]
results = {}
with ThreadPoolExecutor(max_workers=5) as pool:
futures = {pool.submit(remove_background, url): url for url in source_urls}
for future in as_completed(futures):
url = futures[future]
try:
results[url] = future.result()
except Exception as exc:
results[url] = None
print(f"failed: {url}: {exc}")
Halten Sie max_workers maßvoll – zu häufiges Abfragen bei vielen parallelen Tasks verbraucht nur Ihr Anfragekontingent und beschleunigt die Generierung nicht, da die Wandzeit jedes Tasks hauptsächlich von der Modellinferenz bestimmt wird, nicht von Ihrer Abfragefrequenz.
Produktionshärtung: exakte Komposition, Callbacks, Idempotenz, Fehler
Exakte Produktkomposition beibehalten. Bei Katalogarbeiten können Sie es sich meist nicht leisten, dass das Modell das Bild neu komponiert oder das Motiv leicht beschneidet – ein in der Eingabe zentrierter Schuh muss auch in der Ausgabe zentriert bleiben. seedream-5.0-pro/image-to-image unterstützt einen aspect_ratio-Wert, den die Lite-Stufe nicht bietet: match_input_image, wodurch die Ausgabefläche auf die Abmessungen des Eingabebilds festgelegt wird, statt ein festes Seitenverhältnis zu erzwingen. Es akzeptiert außerdem bis zu 10 image_urls pro Aufruf und beschränkt resolution auf 1K/2K (eine andere Auflösungsmenge als bei Lite – gehen Sie nicht davon aus, dass die Schemas der seedream-Endpunkte einheitlich sind; jeder Endpunkt hat seine eigenen Enum-Werte). Für reine Hintergrundentfernungs- und -ersetzungsarbeiten, bei denen die Komposition exakt übereinstimmen muss, ist dies die Stufe der Wahl, zu höheren Kosten pro Bild – aktuelle Tarife finden Sie unter Preise.
Wenn Sie mehrere Quellperspektiven gleichzeitig referenzieren müssen (z. B. Vorder- und Seitenansicht desselben Produkts), statt ein Bild pro Aufruf zu verarbeiten, ist nano-banana-2 eine sinnvolle Alternative – es akzeptiert Referenzbilder über image_input (nicht image_urls), daneben kann resolution die Werte 1K/2K/4K annehmen.
Callbacks statt Polling verwenden. Für Stapeljobs jeder realistischen Größe sind Webhooks dem Polling vorzuziehen: Fügen Sie ein callback-Objekt als Geschwister von input hinzu – nicht darin verschachtelt, POST /v1/tasks lehnt diese Struktur ab:
task_input = {
"prompt": BACKGROUND_PROMPT,
"image_urls": [image_url],
"aspect_ratio": "1:1",
"resolution": "2K",
}
resp = requests.post(f"{API}/tasks", headers=HEADERS, json={
"model": "seedream-5.0-lite/image-to-image",
"input": task_input,
"callback": {"url": "https://your-service.example.com/hooks/hiapi", "when": "final"},
}, timeout=60)
Nachdem ein Task einen Endzustand erreicht hat, sendet hiapi per POST dasselbe data-Objekt an Ihre Callback-URL, das auch GET /v1/tasks/{taskId} zurückgeben würde. Wenn Sie die Echtheit des Callbacks serverseitig prüfen möchten, lesen Sie den optionalen X-HiAPI-Signature-HMAC-Header in der Referenz zur asynchronen Task-API.
Idempotenz. Es gibt kein dokumentiertes idempotency_key-Feld bei POST /v1/tasks – bauen Sie Idempotenz auf Anwendungsebene auf. Verwenden Sie einen kleinen Speicher (eine Datenbankzeile, einen Redis-Schlüssel oder sogar eine lokale Datei für einmalige Skripte), als Schlüssel den Hash von (image_url, prompt, model), und prüfen Sie vor dem Absenden eines neuen Tasks, ob für diesen Schlüssel bereits eine taskId oder Ausgabe-URL gespeichert ist. Wenn Ihr Stapeljob mittendrin abstürzt und erneut ausgeführt wird, können Sie die doppelte Abrechnung bereits verarbeiteter Bilder überspringen, statt die Kosten stillschweigend zu erhöhen.
Fehlerbehandlung – drei verschiedene Formen, nicht gleich behandeln:
- Anfragevalidierung (fehlerhafte Eingabe bei der Erstellung) – HTTP 400, flache Struktur:
{"code":400,"error_code":"INVALID_REQUEST","message":"...","data":null}. Das bedeutet, Ihrinput-Dictionary passt nicht zum Modellschema – prüfen Sie auf falsch geschriebene Feldnamen oder falsche Enum-Werte. - Authentifizierungsfehler – HTTP 401, anders verschachtelt:
{"error":{"code":"permission_denied","message":"...","request_id":"...","type":"hiapi_error"}}. Der API-Schlüssel fehlt oder ist abgelaufen, nicht die Anfrage ist falsch – nicht wiederholen, Schlüssel korrigieren. - Task-Level-Fehler (Anfrage gültig, aber die Generierung selbst schlägt fehl) – zeigt sich beim Abfragen:
data.status == "fail",data.errorbeschreibt den Grund. Dies ist wiederholbar; vorübergehende Upstream-Fehler können nach erneuter Übermittlung erfolgreich sein.
if task["status"] == "fail":
err = task.get("error") or {}
# log err["code"] / err["message"], then decide: retry, skip, or alert
Fassen Sie nicht alle drei in ein einziges except Exception zusammen – ein 401, das in einer Schleife wiederholt wird, verbraucht nur Ihr Rate-Limit und wird nie erfolgreich sein, während ein Task-Level-fail beim zweiten Versuch durchaus erfolgreich sein kann.
Nächste Schritte
- Referenz zur asynchronen Task-API – vollständiger Lebenszyklus, Callback-Signatur, alle Statuswerte
- Modellseiten seedream-5.0-lite/image-to-image und seedream-5.0-pro/image-to-image – Live-Schema und Beispiele
- Eine asynchrone Task-Pipeline aufbauen – wenn die Hintergrundentfernung eine Stufe in einer größeren Generierungspipeline ist
- Beheben, wenn hiapi-Task-Callbacks nicht ausgelöst werden – eine Debugging-Checkliste, falls Ihr Webhook stumm bleibt
- Flux 2 Klein 9B Image-to-Image-Prompts – Prompt-Muster eines weiteren i2i-Modells zum Vergleich
- AI Product Photo Lab – eine Version desselben Workflows ohne Code
Häufig gestellte Fragen
Wird der Hintergrund wirklich entfernt oder nur überdeckt? Funktional beides – das Modell generiert die gesamte Fläche um das erhaltene Motiv herum neu, sodass keine Restmaske oder ausgefranste Kanten zurückbleiben wie bei Kantenerkennungs-Freistellungswerkzeugen. Der Preis dafür ist, dass im Prompt ausdrücklich „alles andere unverändert lassen“ stehen muss, sonst stilisiert das Modell gerne auch das Motiv mit um.
Kann ich ein transparentes PNG statt eines Volltonhintergrunds erhalten? Fordern Sie es direkt im Prompt an (z. B. „Hintergrund durch transparent ersetzen“ oder „Motiv auf transparentem Hintergrund isolieren“) und verlangen Sie eine PNG-Ausgabe, wo das Modell das Feld output_format unterstützt – die Unterstützung variiert je nach Modell, prüfen Sie daher die Seite des jeweiligen Modells, bevor Sie es als gegeben annehmen.
Warum kommt mein Bild neu komponiert zurück, statt dem Original zu entsprechen? Wahrscheinlich verwenden Sie eine Stufe, deren aspect_ratio-Enum match_input_image nicht enthält – in den Lite-/4.5-Stufen wählen Sie ein festes Seitenverhältnis, das das Quellbild möglicherweise beschneidet oder mit Rändern auffüllt. Wechseln Sie zu seedream-5.0-pro/image-to-image und setzen Sie aspect_ratio auf match_input_image.
Wie viel kostet ein Bild? Die Preise variieren je nach Modell und Auflösungsstufe und ändern sich im Laufe der Zeit – sehen Sie unter Preise nach, statt Zahlen in Ihrem eigenen Code oder Ihrer Dokumentation fest zu kodieren.
Was, wenn meine Bild-URL noch nicht öffentlich ist? Die Task-API ruft Bilder serverseitig per URL ab, daher muss es ohne Authentifizierung erreichbar sein. Laden Sie es zuerst in einen öffentlichen Bucket oder einen CDN-Pfad hoch – signierte/private URLs oder localhost-Pfade schlagen bei der Task-Erstellung fehl oder (schlimmer) stillschweigend während der Verarbeitung.
Ähnliche Artikel
Alle Artikel ansehen →-
Tutorial
So rufen Sie hailuo-2.3-fast/image-to-video über die HiAPI API auf: curl und Python in der Praxis
Die erste lauffähige Anfrage für die schnelle, kostengünstige Bild-zu-Video-Stufe – von der Modell-ID bis zum heruntergeladenen MP4
-
Tutorial
So rufen Sie hailuo-2.3/text-to-video über die HiAPI API auf: curl, Python und lauffähige Anfragebeispiele
-
Tutorial
Kandinsky 6.0 Pro Text-zu-Video auf HiAPI: curl- und Python-Tutorial
Eine anfrageorientierte praktische Demonstration: Aufbau des Aufrufs vom Prompt zum Videoclip, Absenden der Anfrage, Abfragen des Fertigstellungsstatus und Herunterladen des Ergebnisses