API de compression d'images#
Compressez des images PNG, JPEG et WebP avec l'endpoint POST /v1/convert/compress-image — le format ne change jamais (PNG en entrée, PNG en sortie). La compression est d'abord sans perte : les métadonnées sont supprimées et l'image est réencodée avec les réglages sans perte les plus efficaces pour son format, de sorte que le résultat n'est jamais plus volumineux que l'entrée. Transmettez target_size_kb pour définir un budget de taille de fichier ; si l'optimisation sans perte seule ne suffit pas à l'atteindre, les dimensions de l'image sont réduites avec le rapport d'aspect verrouillé jusqu'à ce qu'elle tienne dans le budget.
Endpoint#
POST /v1/convert/compress-image
Content-Type : multipart/form-data
Entrée acceptée : fichiers .png, .jpg, .jpeg, .webp
Format de sortie : identique à l'entrée (image/png, image/jpeg ou image/webp)
Authentification#
Nécessite soit une clé API privée, soit un jeton JWT issu d'une clé publique.
X-API-Key: sk_live_your_private_key
Ou :
Authorization: Bearer <jwt_token>
Paramètres de la requête#
| Paramètre | Type | Obligatoire | Valeur par défaut | Description |
|---|---|---|---|---|
file |
file | Oui | -- | Le fichier image .png, .jpg, .jpeg ou .webp à compresser. |
target_size_kb |
integer |
Non | -- | Taille de fichier cible en kilo-octets. Omis : optimisation sans perte uniquement. Défini : l'image est en plus réduite en dimensions (rapport d'aspect verrouillé) jusqu'à tenir dans la cible. |
output_filename |
string |
Non | Nom du fichier d'entrée | Nom de fichier de sortie personnalisé. L'extension du fichier d'entrée est conservée. |
direct_download |
boolean |
Non | true |
Si true, renvoie les octets bruts de l'image. Si false, renvoie des métadonnées JSON avec une URL de téléchargement présignée. |
Détails de la conversion#
Étape 1 — sans perte (toujours exécutée) :
- Les métadonnées (EXIF, XMP, blocs de texte PNG) sont supprimées ; le profil colorimétrique ICC et l'indicateur d'orientation EXIF sont conservés, afin que les couleurs et la rotation ne changent pas
- PNG : réencodage à la compression zlib maximale, plus une conversion en palette lorsque l'image compte 256 couleurs uniques ou moins et que le résultat est prouvé identique pixel par pixel
- JPEG : réencodage réutilisant les tables de quantification d'origine avec un codage de Huffman progressif optimisé — aucune perte de quantification supplémentaire n'est introduite
- WebP : réencodage véritablement sans perte (VP8L) à l'effort maximal
- Le plus petit fichier parmi les octets d'origine et tous les candidats l'emporte — la sortie n'est jamais plus volumineuse que l'entrée
Étape 2 — réduction des dimensions (uniquement avec target_size_kb, et seulement si l'étape 1 n'atteint pas la cible) :
- Les dimensions de l'image sont réduites avec le rapport d'aspect verrouillé (rééchantillonnage LANCZOS) puis réencodées, le facteur d'échelle étant recherché par dichotomie pour obtenir les plus grandes dimensions qui tiennent dans la cible
- Les JPEG réduits et les WebP issus d'une source lossy sont réencodés à la qualité 85 ; les PNG et les WebP issus d'une source sans perte restent sans perte à la taille réduite
file_size (ou l'en-tête X-File-Size) pour connaître la taille atteinte.
Réponse#
Téléchargement direct (direct_download=true, par défaut)#
HTTP 200 OK
Content-Type: image/png
Content-Disposition: inline; filename="photo_20260717_123456789.png"
Renvoie les octets bruts de l'image dans le même format que l'entrée.
Réponse avec métadonnées (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
}
Exemples de code#
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)
Réponses d'erreur#
| Statut | Condition |
|---|---|
400 Bad Request |
Le fichier n'est pas un fichier .png, .jpg, .jpeg ou .webp |
400 Bad Request |
Le contenu du fichier ne correspond pas à son extension (l'endpoint ne change jamais de format) |
400 Bad Request |
Image animée (APNG / WebP animé) — non prise en charge |
400 Bad Request |
target_size_kb est nul ou négatif |
422 Unprocessable Entity |
target_size_kb est fourni mais n'est pas un nombre entier |
400 Bad Request |
Échec de la conversion de l'image (fichier corrompu ou non pris en charge) |
401 Unauthorized |
Clé API / jeton JWT manquant ou invalide |
402 Payment Required |
Limite mensuelle de conversions atteinte |
402 Payment Required |
Limite de stockage atteinte |
413 Payload Too Large |
Le fichier dépasse la taille maximale autorisée par le forfait |
400 Bad Request |
La zone de l'image dépasse 40 000 000 de pixels (protection contre les bombes de décompression) |
Limites#
| Limite | Valeur |
|---|---|
| Taille de fichier maximale | Selon le forfait (Free : 5 MB) |
| Dimensions maximales de l'image | 40 000 000 de pixels (p. ex. 8000x5000) |
| Formats | PNG, JPEG, WebP (statiques uniquement — pas d'animations) |
| Taille cible | Au mieux — une cible inatteignable renvoie le plus petit fichier réalisable |
| Conversions mensuelles | Selon le forfait |
Questions fréquentes#
Comment compresser une image sans perdre en qualité ?#
Envoyez l'image à /v1/convert/compress-image sans target_size_kb. L'endpoint supprime les métadonnées et réencode avec les réglages sans perte les plus efficaces pour le format — les PNG et les WebP sans perte restent identiques pixel par pixel, et le JPEG conserve ses tables de quantification d'origine, donc aucune perte de quantification supplémentaire n'est introduite. Le résultat n'est jamais plus volumineux que votre fichier d'entrée.
Comment compresser une image à une taille de fichier précise ?#
Transmettez target_size_kb avec votre budget en kilo-octets (par exemple 200 pour 200 Ko). L'optimisation sans perte s'exécute d'abord ; si le fichier dépasse encore le budget, les dimensions de l'image sont réduites avec le rapport d'aspect verrouillé jusqu'à ce qu'il tienne. Si la cible est inatteignable même à l'échelle minimale, vous obtenez le plus petit fichier réalisable plutôt qu'une erreur.
La compression change-t-elle le format de l'image ?#
Non, jamais. Un PNG reste un PNG, un JPEG reste un JPEG, un WebP reste un WebP — l'endpoint rejette les fichiers dont le contenu ne correspond pas à leur extension au lieu de les convertir silencieusement.
Les métadonnées de mon image sont-elles supprimées ?#
Les EXIF, XMP et blocs de texte PNG sont supprimés, ce qui fait souvent gagner de la place à lui seul. Deux éléments sont délibérément conservés : le profil colorimétrique ICC (pour que les couleurs ne dérivent pas dans les visionneuses à gestion des couleurs) et l'indicateur d'orientation EXIF (pour que les photos pivotées s'affichent toujours correctement).
Puis-je compresser des images animées ?#
Non. Les fichiers APNG et WebP animés sont rejetés avec une erreur 400 plutôt que d'être silencieusement aplatis en une seule image.