Bildkomprimierungs-API#

Komprimieren Sie PNG-, JPEG- und WebP-Bilder mit dem Endpunkt POST /v1/convert/compress-image — das Format ändert sich nie (PNG rein, PNG raus). Die Komprimierung arbeitet verlustfrei-zuerst: Metadaten werden entfernt und das Bild wird mit den stärksten verlustfreien Einstellungen seines Formats neu kodiert, sodass das Ergebnis nie größer ist als die Eingabe. Übergeben Sie target_size_kb, um ein Dateigrößen-Budget festzulegen; reicht die verlustfreie Optimierung allein nicht aus, wird das Bild bei fixiertem Seitenverhältnis herunterskaliert, bis es passt.


Endpunkt#

POST /v1/convert/compress-image

Content-Type: multipart/form-data

Akzeptierte Eingabe: .png-, .jpg-, .jpeg-, .webp-Dateien

Ausgabeformat: identisch mit der Eingabe (image/png, image/jpeg oder image/webp)


Authentifizierung#

Erfordert entweder einen privaten API-Schlüssel oder ein JWT-Token eines öffentlichen Schlüssels.

X-API-Key: sk_live_your_private_key

Oder:

Authorization: Bearer <jwt_token>

Request-Parameter#

Parameter Typ Erforderlich Standard Beschreibung
file Datei Ja -- Die zu komprimierende .png-, .jpg-, .jpeg- oder .webp-Bilddatei.
target_size_kb integer Nein -- Ziel-Dateigröße in Kilobyte. Weggelassen: nur verlustfreie Optimierung. Gesetzt: das Bild wird zusätzlich herunterskaliert (Seitenverhältnis fixiert), bis es das Ziel erreicht.
output_filename string Nein Eingabedateiname Benutzerdefinierter Ausgabedateiname. Die Endung der Eingabedatei bleibt erhalten.
direct_download boolean Nein true Bei true werden rohe Bilddaten zurückgegeben. Bei false werden JSON-Metadaten mit einer presigned Download-URL zurückgegeben.

Details zur Konvertierung#

Stufe 1 — verlustfrei (läuft immer):

  • Metadaten (EXIF, XMP, PNG-Textchunks) werden entfernt; das ICC-Farbprofil und das EXIF-Orientierungsflag bleiben erhalten, damit sich Farben und Ausrichtung nicht ändern
  • PNG: Neukodierung mit maximaler zlib-Kompression, plus Palettenkonvertierung, wenn das Bild 256 oder weniger eindeutige Farben hat und das Ergebnis nachweislich pixelidentisch ist
  • JPEG: Neukodierung unter Wiederverwendung der ursprünglichen Quantisierungstabellen mit optimierter progressiver Huffman-Kodierung — es entsteht kein zusätzlicher Quantisierungsverlust
  • WebP: echte verlustfreie Neukodierung (VP8L) mit maximalem Aufwand
  • Die kleinste Variante aus den Original-Bytes und allen Kandidaten gewinnt — die Ausgabe ist nie größer als die Eingabe

Stufe 2 — Reduzierung der Abmessungen (nur mit target_size_kb, nur wenn Stufe 1 das Ziel verfehlt):

  • Das Bild wird bei fixiertem Seitenverhältnis herunterskaliert (LANCZOS-Resampling) und neu kodiert; der Skalierungsfaktor wird per Binärsuche auf die größten Abmessungen bestimmt, die in das Ziel passen
  • Herunterskalierte JPEGs und WebP aus verlustbehafteter Quelle werden mit Qualität 85 neu kodiert; PNG und WebP aus verlustfreier Quelle bleiben in der reduzierten Größe verlustfrei
Hinweis zu Best-Effort: Ist das Ziel selbst bei minimaler Skalierung unerreichbar, gibt der Endpunkt statt eines Fehlers die kleinste erreichte Datei zurück — prüfen Sie file_size (oder den X-File-Size-Header), um zu sehen, was erreicht wurde.

Antwort#

Direkter Download (direct_download=true, Standard)#

HTTP 200 OK
Content-Type: image/png
Content-Disposition: inline; filename="photo_20260717_123456789.png"

Liefert rohe Bilddaten im selben Format wie die Eingabe.

Metadaten-Antwort (direct_download=false)#

{
    "presigned_url": "https://spaces.example.com/...",
    "object_key": "env/files/{project_id}/compress-image/photo_20260717_123456789.png",
    "filename": "photo_20260717_123456789.png",
    "file_size": 45678,
    "conversion_time_seconds": 0.5
}

Codebeispiele#

Python#

import requests

with open("photo.png", "rb") as f:
    response = requests.post(
        "https://api.enconvert.com/v1/convert/compress-image",
        headers={"X-API-Key": "sk_live_your_private_key"},
        files={"file": ("photo.png", f)},
        data={"target_size_kb": 200}
    )

with open("photo_compressed.png", "wb") as out:
    out.write(response.content)

Node.js#

const form = new FormData();
form.append("file", fs.createReadStream("photo.png"));
form.append("target_size_kb", "200");

const response = await fetch("https://api.enconvert.com/v1/convert/compress-image", {
    method: "POST",
    headers: { "X-API-Key": "sk_live_your_private_key" },
    body: form
});

fs.writeFileSync("photo_compressed.png", Buffer.from(await response.arrayBuffer()));

PHP#

$ch = curl_init("https://api.enconvert.com/v1/convert/compress-image");
curl_setopt_array($ch, [
    CURLOPT_POST => true,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => ["X-API-Key: sk_live_your_private_key"],
    CURLOPT_POSTFIELDS => [
        "file" => new CURLFile("photo.png"),
        "target_size_kb" => 200
    ]
]);
$output = curl_exec($ch);
curl_close($ch);
file_put_contents("photo_compressed.png", $output);

Go#

body := &bytes.Buffer{}
writer := multipart.NewWriter(body)
part, _ := writer.CreateFormFile("file", "photo.png")
file, _ := os.Open("photo.png")
io.Copy(part, file)
writer.WriteField("target_size_kb", "200")
writer.Close()

req, _ := http.NewRequest("POST", "https://api.enconvert.com/v1/convert/compress-image", body)
req.Header.Set("Content-Type", writer.FormDataContentType())
req.Header.Set("X-API-Key", "sk_live_your_private_key")
resp, _ := http.DefaultClient.Do(req)

Fehlerantworten#

Status Bedingung
400 Bad Request Datei ist keine .png-, .jpg-, .jpeg- oder .webp-Datei
400 Bad Request Dateiinhalt passt nicht zur Dateiendung (der Endpunkt ändert niemals das Format)
400 Bad Request Animiertes Bild (APNG / animiertes WebP) — nicht unterstützt
400 Bad Request target_size_kb ist null oder negativ
422 Unprocessable Entity target_size_kb ist angegeben, aber keine ganze Zahl
400 Bad Request Bildkonvertierung fehlgeschlagen (beschädigte oder nicht unterstützte Datei)
401 Unauthorized Fehlender oder ungültiger API-Schlüssel / JWT-Token
402 Payment Required Monatliches Konvertierungslimit erreicht
402 Payment Required Speicherlimit erreicht
413 Payload Too Large Datei überschreitet die maximale Dateigröße des Plans
400 Bad Request Bildfläche überschreitet 40.000.000 Pixel (Schutz vor Dekompressionsbomben)

Limits#

Limit Wert
Maximale Dateigröße Abhängig vom Plan (Free: 5 MB)
Maximale Bildabmessungen 40.000.000 Pixel (z. B. 8000x5000)
Formate PNG, JPEG, WebP (nur statisch — keine Animationen)
Zielgröße Best-Effort — bei unerreichbaren Zielen wird die kleinste erreichbare Datei zurückgegeben
Monatliche Konvertierungen Abhängig vom Plan

Häufig gestellte Fragen#

Wie komprimiere ich ein Bild ohne Qualitätsverlust?#

Senden Sie das Bild ohne target_size_kb an /v1/convert/compress-image. Der Endpunkt entfernt Metadaten und kodiert mit den stärksten verlustfreien Einstellungen des Formats neu — PNG und verlustfreies WebP bleiben pixelidentisch, und JPEG behält seine ursprünglichen Quantisierungstabellen, sodass kein weiterer Quantisierungsverlust entsteht. Das Ergebnis ist nie größer als Ihre Eingabe.

Wie komprimiere ich ein Bild auf eine bestimmte Dateigröße?#

Übergeben Sie target_size_kb mit Ihrem Budget in Kilobyte (zum Beispiel 200 für 200 KB). Zuerst läuft die verlustfreie Optimierung; liegt die Datei danach noch über dem Budget, wird das Bild bei fixiertem Seitenverhältnis herunterskaliert, bis es passt. Ist das Ziel selbst bei minimaler Skalierung unerreichbar, erhalten Sie statt eines Fehlers die kleinste erreichbare Datei.

Ändert die Komprimierung das Bildformat?#

Nein, niemals. PNG bleibt PNG, JPEG bleibt JPEG, WebP bleibt WebP — der Endpunkt lehnt Dateien ab, deren Inhalt nicht zur Endung passt, statt sie stillschweigend zu konvertieren.

Werden meine Bild-Metadaten entfernt?#

EXIF, XMP und PNG-Textchunks werden entfernt, was oft schon für sich genommen Speicherplatz spart. Zwei Dinge bleiben bewusst erhalten: das ICC-Farbprofil (damit sich Farben in farbverwalteten Viewern nicht verschieben) und das EXIF-Orientierungsflag (damit gedrehte Fotos weiterhin korrekt angezeigt werden).

Kann ich animierte Bilder komprimieren?#

Nein. APNG- und animierte WebP-Dateien werden mit einem 400-Fehler abgelehnt, statt stillschweigend auf ein einzelnes Frame reduziert zu werden.