API-Referenz
Vollständige Anleitung zur Verwendung der Qwen Image Edit API
API-Referenz
Vollständige Dokumentation aller verfügbaren Methoden und Parameter der Qwen Image Edit API.
🔐 Authentifizierung
API-Schlüssel Setup
import { QwenImageEdit } from 'qwen-image-edit';
// Grundlegende Authentifizierung
const editor = new QwenImageEdit({
apiKey: 'ihr-api-schluessel',
region: 'eu-west-1' // Optional: eu-west-1, us-east-1, ap-southeast-1
});
// Mit erweiterten Optionen
const editor = new QwenImageEdit({
apiKey: process.env.QWEN_API_KEY,
region: 'eu-west-1',
timeout: 30000,
maxRetries: 3,
baseURL: 'https://api.qwen.com/v1' // Optional: Custom endpoint
});
Umgebungsvariablen
# .env Datei
QWEN_API_KEY=ihr-api-schluessel
QWEN_REGION=eu-west-1
QWEN_TIMEOUT=30000
🎯 Kern-Methoden
editText()
Bearbeitet Text in Bildern mit natürlicher Sprache.
interface EditTextOptions {
image: string | Buffer | File; // Bildquelle
prompt: string; // Bearbeitungsanweisung
quality?: 'low' | 'medium' | 'high'; // Ausgabequalität (Standard: 'medium')
format?: 'jpg' | 'png' | 'webp'; // Ausgabeformat (Standard: 'jpg')
preserveAspectRatio?: boolean; // Seitenverhältnis beibehalten (Standard: true)
maxWidth?: number; // Maximale Breite in Pixeln
maxHeight?: number; // Maximale Höhe in Pixeln
}
interface EditTextResponse {
imageUrl: string; // URL des bearbeiteten Bildes
credits: number; // Verwendete Credits
processingTime: number; // Verarbeitungszeit in ms
metadata: {
originalSize: { width: number; height: number };
outputSize: { width: number; height: number };
format: string;
quality: string;
};
}
Beispiele:
// Einfache Textbearbeitung
const result = await editor.editText({
image: './poster.jpg',
prompt: 'Ändere "Konzert" zu "Festival" im Haupttitel'
});
// Mit erweiterten Optionen
const result = await editor.editText({
image: './werbung.jpg',
prompt: 'Übersetze allen Text ins Deutsche und verbessere die Typografie',
quality: 'high',
format: 'png',
maxWidth: 1920,
preserveAspectRatio: true
});
// Mit Buffer
const bildBuffer = fs.readFileSync('./bild.jpg');
const result = await editor.editText({
image: bildBuffer,
prompt: 'Korrigiere alle Rechtschreibfehler'
});
editElement()
Fügt Elemente hinzu, entfernt oder modifiziert sie in Bildern.
interface EditElementOptions {
image: string | Buffer | File;
prompt: string;
action?: 'add' | 'remove' | 'modify'; // Aktion (Standard: 'add')
position?: string; // Position für neue Elemente
style?: string; // Stil-Anweisungen
blendMode?: 'normal' | 'multiply' | 'overlay' | 'soft-light';
opacity?: number; // Transparenz (0-1)
quality?: 'low' | 'medium' | 'high';
format?: 'jpg' | 'png' | 'webp';
}
interface EditElementResponse {
imageUrl: string;
credits: number;
processingTime: number;
elementsDetected: number; // Anzahl erkannter Elemente
elementsModified: number; // Anzahl modifizierter Elemente
metadata: {
originalSize: { width: number; height: number };
outputSize: { width: number; height: number };
format: string;
modifications: Array<{
type: 'add' | 'remove' | 'modify';
element: string;
position?: { x: number; y: number; width: number; height: number };
}>;
};
}
Beispiele:
// Logo hinzufügen
const result = await editor.editElement({
image: './produkt.jpg',
prompt: 'Füge das Firmenlogo in die untere rechte Ecke ein',
action: 'add',
position: 'bottom-right',
opacity: 0.8
});
// Wasserzeichen entfernen
const result = await editor.editElement({
image: './bild-mit-wasserzeichen.jpg',
prompt: 'Entferne alle Wasserzeichen',
action: 'remove'
});
// Element modifizieren
const result = await editor.editElement({
image: './banner.jpg',
prompt: 'Mache den Button größer und ändere die Farbe zu blau',
action: 'modify',
style: 'modern und auffällig'
});
transferStyle()
Überträgt den Stil eines Bildes auf ein anderes.
interface TransferStyleOptions {
sourceImage: string | Buffer | File; // Quellbild
styleImage: string | Buffer | File; // Stil-Referenzbild
intensity?: number; // Stil-Intensität (0-1, Standard: 0.7)
preserveContent?: boolean; // Inhalt beibehalten (Standard: true)
styleAspects?: Array<'color' | 'texture' | 'lighting' | 'composition'>;
quality?: 'low' | 'medium' | 'high';
format?: 'jpg' | 'png' | 'webp';
}
interface TransferStyleResponse {
imageUrl: string;
credits: number;
processingTime: number;
styleAnalysis: {
dominantColors: string[];
textureComplexity: 'low' | 'medium' | 'high';
lightingType: 'natural' | 'artificial' | 'mixed';
artisticStyle: string;
};
metadata: {
originalSize: { width: number; height: number };
outputSize: { width: number; height: number };
format: string;
styleIntensity: number;
};
}
Beispiele:
// Grundlegende Stil-Übertragung
const result = await editor.transferStyle({
sourceImage: './portrait.jpg',
styleImage: './van-gogh-stil.jpg',
intensity: 0.8
});
// Selektive Stil-Aspekte
const result = await editor.transferStyle({
sourceImage: './landschaft.jpg',
styleImage: './vintage-foto.jpg',
intensity: 0.6,
styleAspects: ['color', 'lighting'],
preserveContent: true
});
// Fotografischer Stil
const result = await editor.transferStyle({
sourceImage: './produkt.jpg',
styleImage: './professionelle-produktfotografie.jpg',
intensity: 0.5,
styleAspects: ['lighting', 'composition']
});
analyzeImage()
Analysiert Bilder und extrahiert detaillierte Informationen.
interface AnalyzeImageOptions {
image: string | Buffer | File;
analysisTypes?: Array<'text' | 'objects' | 'faces' | 'colors' | 'style' | 'quality' | 'content'>;
language?: string; // Sprache für Textextraktion (Standard: 'auto')
includeCoordinates?: boolean; // Koordinaten für erkannte Elemente
confidenceThreshold?: number; // Mindest-Konfidenz (0-1, Standard: 0.5)
}
interface AnalyzeImageResponse {
credits: number;
processingTime: number;
analysis: {
text?: {
content: string;
language: string;
confidence: number;
regions: Array<{
text: string;
coordinates: { x: number; y: number; width: number; height: number };
confidence: number;
}>;
};
objects?: Array<{
name: string;
confidence: number;
coordinates: { x: number; y: number; width: number; height: number };
attributes: string[];
}>;
faces?: Array<{
confidence: number;
coordinates: { x: number; y: number; width: number; height: number };
attributes: {
age?: number;
gender?: 'male' | 'female';
emotion?: string;
glasses?: boolean;
};
}>;
colors?: {
dominant: string[];
palette: Array<{ color: string; percentage: number }>;
colorScheme: 'monochrome' | 'analogous' | 'complementary' | 'triadic';
};
style?: {
category: string;
subcategory: string;
confidence: number;
characteristics: string[];
};
quality?: {
overall: number;
sharpness: number;
brightness: number;
contrast: number;
noise: number;
resolution: 'low' | 'medium' | 'high';
};
content?: {
category: string;
tags: string[];
description: string;
appropriateness: 'safe' | 'questionable' | 'unsafe';
};
};
metadata: {
imageSize: { width: number; height: number };
format: string;
fileSize: number;
};
}
Beispiele:
// Vollständige Analyse
const result = await editor.analyzeImage({
image: './komplexes-bild.jpg',
analysisTypes: ['text', 'objects', 'colors', 'quality'],
includeCoordinates: true
});
// Nur Textextraktion
const result = await editor.analyzeImage({
image: './dokument.jpg',
analysisTypes: ['text'],
language: 'de',
confidenceThreshold: 0.8
});
// Qualitätsbewertung
const result = await editor.analyzeImage({
image: './foto.jpg',
analysisTypes: ['quality', 'style']
});
🛠️ Hilfsmethoden
resizeImage()
Ändert die Größe von Bildern mit intelligenter Inhaltserhaltung.
interface ResizeImageOptions {
image: string | Buffer | File;
width?: number;
height?: number;
aspectRatio?: string; // z.B. '16:9', '1:1', '4:3'
resizeMode?: 'fit' | 'fill' | 'crop' | 'stretch';
maintainContent?: boolean; // Intelligente Inhaltserhaltung
quality?: 'low' | 'medium' | 'high';
format?: 'jpg' | 'png' | 'webp';
}
interface ResizeImageResponse {
imageUrl: string;
credits: number;
processingTime: number;
metadata: {
originalSize: { width: number; height: number };
outputSize: { width: number; height: number };
resizeRatio: number;
contentPreserved: boolean;
};
}
Beispiele:
// Größe mit Seitenverhältnis ändern
const result = await editor.resizeImage({
image: './original.jpg',
aspectRatio: '16:9',
resizeMode: 'fit',
maintainContent: true
});
// Spezifische Abmessungen
const result = await editor.resizeImage({
image: './banner.jpg',
width: 1200,
height: 600,
resizeMode: 'crop'
});
enhanceImage()
Verbessert die Bildqualität mit KI-gestützten Algorithmen.
interface EnhanceImageOptions {
image: string | Buffer | File;
enhancements?: Array<'sharpen' | 'denoise' | 'brighten' | 'contrast' | 'saturation' | 'upscale'>;
intensity?: number; // Intensität (0-1, Standard: 0.5)
preserveOriginalStyle?: boolean; // Originalstil beibehalten
quality?: 'low' | 'medium' | 'high';
format?: 'jpg' | 'png' | 'webp';
}
interface EnhanceImageResponse {
imageUrl: string;
credits: number;
processingTime: number;
enhancements: Array<{
type: string;
applied: boolean;
intensity: number;
}>;
metadata: {
originalSize: { width: number; height: number };
outputSize: { width: number; height: number };
qualityImprovement: number;
};
}
Beispiele:
// Automatische Verbesserung
const result = await editor.enhanceImage({
image: './altes-foto.jpg',
enhancements: ['sharpen', 'denoise', 'brighten'],
intensity: 0.7
});
// Hochskalierung
const result = await editor.enhanceImage({
image: './kleines-bild.jpg',
enhancements: ['upscale', 'sharpen'],
quality: 'high'
});
cleanImage()
Entfernt unerwünschte Elemente aus Bildern.
interface CleanImageOptions {
image: string | Buffer | File;
removeTypes?: Array<'watermarks' | 'text' | 'logos' | 'people' | 'objects' | 'background'>;
customPrompt?: string; // Benutzerdefinierte Entfernungsanweisung
preserveAreas?: Array<{ // Bereiche, die erhalten bleiben sollen
x: number;
y: number;
width: number;
height: number;
}>;
quality?: 'low' | 'medium' | 'high';
format?: 'jpg' | 'png' | 'webp';
}
interface CleanImageResponse {
imageUrl: string;
credits: number;
processingTime: number;
removedElements: Array<{
type: string;
confidence: number;
coordinates: { x: number; y: number; width: number; height: number };
}>;
metadata: {
originalSize: { width: number; height: number };
outputSize: { width: number; height: number };
cleaningSuccess: number;
};
}
Beispiele:
// Wasserzeichen entfernen
const result = await editor.cleanImage({
image: './bild-mit-wasserzeichen.jpg',
removeTypes: ['watermarks', 'logos']
});
// Benutzerdefinierte Reinigung
const result = await editor.cleanImage({
image: './unordentliches-bild.jpg',
customPrompt: 'Entferne alle störenden Objekte im Hintergrund',
preserveAreas: [
{ x: 100, y: 100, width: 200, height: 200 } // Hauptobjekt erhalten
]
});
⚙️ Erweiterte Konfiguration
Client-Konfiguration
const editor = new QwenImageEdit({
// Authentifizierung
apiKey: 'ihr-api-schluessel',
region: 'eu-west-1',
// Netzwerk
timeout: 60000, // Timeout in ms
maxRetries: 3, // Maximale Wiederholungen
retryDelay: 1000, // Verzögerung zwischen Wiederholungen
// Proxy (optional)
proxy: {
host: 'proxy.example.com',
port: 8080,
auth: {
username: 'benutzer',
password: 'passwort'
}
},
// Cache (optional)
cache: {
enabled: true,
maxSize: 100, // Maximale Anzahl gecachter Bilder
ttl: 3600000 // Cache-Lebensdauer in ms
},
// Logging
debug: true, // Debug-Modus aktivieren
logger: console, // Custom Logger
// Rate Limiting
rateLimit: {
requests: 100, // Anfragen pro Zeitraum
period: 60000 // Zeitraum in ms
}
});
Batch-Verarbeitung
// Batch-Methode für mehrere Bilder
const results = await editor.batchProcess({
operations: [
{
type: 'editText',
image: './bild1.jpg',
prompt: 'Übersetze ins Deutsche'
},
{
type: 'editElement',
image: './bild2.jpg',
prompt: 'Füge Logo hinzu'
},
{
type: 'transferStyle',
sourceImage: './bild3.jpg',
styleImage: './stil.jpg'
}
],
concurrency: 3, // Gleichzeitige Verarbeitungen
onProgress: (completed, total) => {
console.log(`Fortschritt: ${completed}/${total}`);
}
});
🚨 Fehlerbehandlung
Fehlertypen
interface QwenError extends Error {
code: string;
statusCode?: number;
details?: any;
retryable?: boolean;
}
// Häufige Fehlercodes
const ERROR_CODES = {
// Authentifizierung
INVALID_API_KEY: 'Ungültiger API-Schlüssel',
INSUFFICIENT_CREDITS: 'Nicht genügend Credits',
RATE_LIMIT_EXCEEDED: 'Rate-Limit überschritten',
// Bild-Fehler
INVALID_IMAGE_FORMAT: 'Ungültiges Bildformat',
IMAGE_TOO_LARGE: 'Bild zu groß',
IMAGE_CORRUPTED: 'Beschädigtes Bild',
// Verarbeitung
PROCESSING_FAILED: 'Verarbeitung fehlgeschlagen',
CONTENT_NOT_DETECTED: 'Inhalt nicht erkannt',
UNSUPPORTED_OPERATION: 'Nicht unterstützte Operation',
// Netzwerk
NETWORK_ERROR: 'Netzwerkfehler',
TIMEOUT: 'Zeitüberschreitung',
SERVICE_UNAVAILABLE: 'Service nicht verfügbar'
};
Fehlerbehandlung
try {
const result = await editor.editText({
image: './bild.jpg',
prompt: 'Bearbeite das Bild'
});
console.log('Erfolgreich:', result.imageUrl);
} catch (error) {
if (error.code === 'INSUFFICIENT_CREDITS') {
console.error('Nicht genügend Credits. Bitte laden Sie Ihr Konto auf.');
} else if (error.code === 'IMAGE_TOO_LARGE') {
console.error('Bild ist zu groß. Maximale Größe: 10MB');
} else if (error.retryable) {
console.log('Wiederholbarer Fehler, versuche erneut...');
// Implementiere Retry-Logik
} else {
console.error('Unerwarteter Fehler:', error.message);
}
}
Robuste Fehlerbehandlung mit Wiederholung
import pRetry from 'p-retry';
async function robustEditText(options) {
return pRetry(async () => {
try {
return await editor.editText(options);
} catch (error) {
// Nicht wiederholbare Fehler sofort abbrechen
if (!error.retryable) {
throw new pRetry.AbortError(error);
}
throw error;
}
}, {
retries: 3,
factor: 2,
minTimeout: 1000,
maxTimeout: 10000
});
}
📊 Limits und Kontingente
Rate Limits
Plan | Anfragen/Minute | Anfragen/Tag | Gleichzeitige Anfragen |
---|---|---|---|
Free | 10 | 100 | 1 |
Basic | 60 | 1,000 | 3 |
Pro | 300 | 10,000 | 10 |
Enterprise | Unbegrenzt | Unbegrenzt | 50 |
Bildlimits
Eigenschaft | Limit |
---|---|
Maximale Dateigröße | 10 MB |
Maximale Auflösung | 4096 x 4096 px |
Unterstützte Formate | JPG, PNG, WebP, GIF |
Minimale Auflösung | 64 x 64 px |
Credit-Verbrauch
Operation | Credits |
---|---|
editText (einfach) | 1-3 |
editText (komplex) | 3-5 |
editElement | 2-4 |
transferStyle | 3-6 |
analyzeImage | 1-2 |
resizeImage | 0.5-1 |
enhanceImage | 2-4 |
cleanImage | 2-5 |
🔗 Webhooks
Webhook-Konfiguration
// Webhook für asynchrone Verarbeitung einrichten
const webhookConfig = {
url: 'https://ihre-domain.com/webhook',
secret: 'ihr-webhook-secret',
events: ['processing.completed', 'processing.failed']
};
// Asynchrone Verarbeitung starten
const job = await editor.editTextAsync({
image: './grosses-bild.jpg',
prompt: 'Komplexe Bearbeitung',
webhook: webhookConfig
});
console.log('Job gestartet:', job.id);
Webhook-Handler
// Express.js Webhook-Handler
app.post('/webhook', express.raw({type: 'application/json'}), (req, res) => {
const signature = req.headers['x-qwen-signature'];
const payload = req.body;
// Signatur verifizieren
const expectedSignature = crypto
.createHmac('sha256', webhookConfig.secret)
.update(payload)
.digest('hex');
if (signature !== `sha256=${expectedSignature}`) {
return res.status(401).send('Ungültige Signatur');
}
const event = JSON.parse(payload);
switch (event.type) {
case 'processing.completed':
console.log('Verarbeitung abgeschlossen:', event.data.imageUrl);
break;
case 'processing.failed':
console.error('Verarbeitung fehlgeschlagen:', event.data.error);
break;
}
res.status(200).send('OK');
});
📱 SDKs
JavaScript/TypeScript
npm install qwen-image-edit
# oder
yarn add qwen-image-edit
Python
pip install qwen-image-edit
from qwen_image_edit import QwenImageEdit
editor = QwenImageEdit(
api_key='ihr-api-schluessel',
region='eu-west-1'
)
result = editor.edit_text(
image='./bild.jpg',
prompt='Übersetze ins Deutsche'
)
print(f'Bearbeitetes Bild: {result.image_url}')
PHP
composer require qwen/image-edit
<?php
use Qwen\ImageEdit\QwenImageEdit;
$editor = new QwenImageEdit([
'apiKey' => 'ihr-api-schluessel',
'region' => 'eu-west-1'
]);
$result = $editor->editText([
'image' => './bild.jpg',
'prompt' => 'Übersetze ins Deutsche'
]);
echo "Bearbeitetes Bild: " . $result['imageUrl'];
?>
Java
<dependency>
<groupId>com.qwen</groupId>
<artifactId>image-edit</artifactId>
<version>1.0.0</version>
</dependency>
import com.qwen.imageedit.QwenImageEdit;
import com.qwen.imageedit.EditTextOptions;
QwenImageEdit editor = new QwenImageEdit.Builder()
.apiKey("ihr-api-schluessel")
.region("eu-west-1")
.build();
EditTextOptions options = new EditTextOptions.Builder()
.image("./bild.jpg")
.prompt("Übersetze ins Deutsche")
.build();
EditTextResponse result = editor.editText(options);
System.out.println("Bearbeitetes Bild: " + result.getImageUrl());
Go
go get github.com/qwen/image-edit-go
package main
import (
"fmt"
"github.com/qwen/image-edit-go"
)
func main() {
editor := qwenimageedit.New(&qwenimageedit.Config{
APIKey: "ihr-api-schluessel",
Region: "eu-west-1",
})
result, err := editor.EditText(&qwenimageedit.EditTextOptions{
Image: "./bild.jpg",
Prompt: "Übersetze ins Deutsche",
})
if err != nil {
panic(err)
}
fmt.Printf("Bearbeitetes Bild: %s\n", result.ImageURL)
}
Ruby
gem install qwen-image-edit
require 'qwen/image_edit'
editor = Qwen::ImageEdit.new(
api_key: 'ihr-api-schluessel',
region: 'eu-west-1'
)
result = editor.edit_text(
image: './bild.jpg',
prompt: 'Übersetze ins Deutsche'
)
puts "Bearbeitetes Bild: #{result.image_url}"