API di Compressione Immagini#
Comprimi immagini PNG, JPEG e WebP con l'endpoint POST /v1/convert/compress-image — il formato non cambia mai (PNG in ingresso, PNG in uscita). La compressione è prima di tutto lossless: i metadati vengono rimossi e l'immagine viene ricodificata con le impostazioni lossless più aggressive per il suo formato, quindi il risultato non è mai più grande dell'input. Passa target_size_kb per impostare un budget di dimensione file; se la sola ottimizzazione lossless non basta a raggiungerlo, l'immagine viene ridimensionata verso il basso con le proporzioni bloccate finché non rientra nel budget.
Endpoint#
POST /v1/convert/compress-image
Content-Type: multipart/form-data
Input accettato: file .png, .jpg, .jpeg, .webp
Formato di output: lo stesso dell'input (image/png, image/jpeg o image/webp)
Autenticazione#
Richiede una chiave API privata oppure un token JWT generato da una chiave pubblica.
X-API-Key: sk_live_your_private_key
Oppure:
Authorization: Bearer <jwt_token>
Parametri della richiesta#
| Parametro | Tipo | Obbligatorio | Predefinito | Descrizione |
|---|---|---|---|---|
file |
file | Sì | -- | Il file immagine .png, .jpg, .jpeg o .webp da comprimere. |
target_size_kb |
integer |
No | -- | Dimensione file di destinazione in kilobyte. Omesso: solo ottimizzazione lossless. Impostato: l'immagine viene inoltre ridimensionata verso il basso (proporzioni bloccate) finché non rientra nel target. |
output_filename |
string |
No | Nome del file di input | Nome file di output personalizzato. L'estensione del file di input viene preservata. |
direct_download |
boolean |
No | true |
Se true, restituisce i byte grezzi dell'immagine. Se false, restituisce metadati JSON con un URL di download presigned. |
Dettagli della conversione#
Fase 1 — lossless (sempre eseguita):
- I metadati (EXIF, XMP, chunk di testo PNG) vengono rimossi; il profilo colore ICC e il flag di orientamento EXIF vengono preservati, così colori e rotazione non cambiano
- PNG: ricodificato alla massima compressione zlib, più una conversione in palette quando l'immagine ha 256 colori unici o meno e il risultato è dimostrabilmente identico pixel per pixel
- JPEG: ricodificato riutilizzando le tabelle di quantizzazione originali con codifica Huffman progressiva ottimizzata — non viene introdotta alcuna perdita di quantizzazione aggiuntiva
- WebP: ricodifica true lossless (VP8L) al massimo livello di effort
- Vince il più piccolo tra i byte originali e tutti i candidati — l'output non è mai più grande dell'input
Fase 2 — riduzione delle dimensioni (solo con target_size_kb, solo se la fase 1 non lo raggiunge):
- L'immagine viene ridimensionata verso il basso con le proporzioni bloccate (ricampionamento LANCZOS) e ricodificata, cercando con una ricerca binaria sul fattore di scala le dimensioni più grandi che rientrano nel target
- I JPEG ridimensionati e i WebP con sorgente lossy vengono ricodificati a qualità 85; i PNG e i WebP con sorgente lossless restano lossless alla dimensione ridotta
file_size (o l'header X-File-Size) per vedere qual è stato il risultato raggiunto.
Risposta#
Download diretto (direct_download=true, predefinito)#
HTTP 200 OK
Content-Type: image/png
Content-Disposition: inline; filename="photo_20260717_123456789.png"
Restituisce i byte grezzi dell'immagine nello stesso formato dell'input.
Risposta con metadati (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
}
Esempi di codice#
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)
Risposte di errore#
| Stato | Condizione |
|---|---|
400 Bad Request |
Il file non è un file .png, .jpg, .jpeg o .webp |
400 Bad Request |
Il contenuto del file non corrisponde alla sua estensione (l'endpoint non cambia mai formato) |
400 Bad Request |
Immagine animata (APNG / WebP animato) — non supportata |
400 Bad Request |
target_size_kb è zero o negativo |
422 Unprocessable Entity |
target_size_kb è presente ma non è un numero intero |
400 Bad Request |
Conversione dell'immagine non riuscita (file corrotto o non supportato) |
401 Unauthorized |
Chiave API / token JWT mancante o non valido |
402 Payment Required |
Limite mensile di conversioni raggiunto |
402 Payment Required |
Limite di storage raggiunto |
413 Payload Too Large |
Il file supera la dimensione massima consentita dal piano |
400 Bad Request |
L'area dell'immagine supera i 40.000.000 di pixel (protezione contro le bombe di decompressione) |
Limiti#
| Limite | Valore |
|---|---|
| Dimensione massima del file | Dipende dal piano (Free: 5 MB) |
| Dimensioni massime immagine | 40.000.000 di pixel (es. 8000x5000) |
| Formati | PNG, JPEG, WebP (solo statici — niente animazioni) |
| Dimensione target | Best effort — i target irraggiungibili restituiscono il file più piccolo ottenibile |
| Conversioni mensili | Dipende dal piano |
Domande frequenti#
Come comprimo un'immagine senza perdere qualità?#
Invia l'immagine a /v1/convert/compress-image senza target_size_kb. L'endpoint rimuove i metadati e ricodifica con le impostazioni lossless più aggressive per il formato — PNG e WebP lossless restano identici pixel per pixel, e il JPEG mantiene le sue tabelle di quantizzazione originali quindi non viene introdotta alcuna ulteriore perdita di quantizzazione. Il risultato non è mai più grande del tuo input.
Come comprimo un'immagine fino a una dimensione file specifica?#
Passa target_size_kb con il tuo budget in kilobyte (ad esempio 200 per 200 KB). L'ottimizzazione lossless viene eseguita per prima; se il file è ancora oltre il budget, l'immagine viene ridimensionata verso il basso con le proporzioni bloccate finché non rientra. Se il target è irraggiungibile anche alla scala minima, ottieni il file più piccolo ottenibile invece di un errore.
La compressione cambia il formato dell'immagine?#
No, mai. PNG resta PNG, JPEG resta JPEG, WebP resta WebP — l'endpoint rifiuta i file il cui contenuto non corrisponde all'estensione invece di convertirli silenziosamente.
I metadati della mia immagine vengono rimossi?#
EXIF, XMP e i chunk di testo PNG vengono rimossi, il che spesso fa risparmiare spazio già da solo. Due cose vengono deliberatamente conservate: il profilo colore ICC (così i colori non cambiano nei viewer con gestione del colore) e il flag di orientamento EXIF (così le foto ruotate continuano a essere visualizzate correttamente).
Posso comprimere immagini animate?#
No. I file APNG e WebP animati vengono rifiutati con un errore 400 invece di essere silenziosamente appiattiti a un singolo fotogramma.