Dans les plateformes e-commerce à fort volume et les places de marché multi-vendeurs, l'intégration de nouveaux catalogues de produits se heurte fréquemment à un goulot d'étranglement : les photos fournies par les fabricants et distributeurs présentent des ratios d'aspect hétérogènes, des arrière-plans encombrés et des éclairages variables. Les logiciels de retouche de bureau par lots nécessitent des manipulations manuelles et ne peuvent pas être connectés directement aux architectures internes d'ERP, de PIM (Product Information Management) ou de CMS. Confier ce travail à des graphistes génère des délais d'attente de 24 à 72 heures par référence et majore significativement le coût de traitement par SKU.
L'API REST de vision par ordinateur proposée par Cutout.pro permet d'automatiser le détourage de produits, le recadrage d'objets et l'application d'arrière-plans unis. En intégrant ces fonctionnalités dans un pipeline asynchrone, les équipes techniques peuvent normaliser des milliers de visuels en quelques secondes pour répondre aux exigences strictes d'Amazon, Google Shopping et Shopify : fond blanc pur (#FFFFFF), proportions standardisées et ombres de contact réalistes.
1. Spécifications de l'API et protocole d'authentification
L'API Cutout.pro est accessible via des requêtes HTTPS sécurisées. L'authentification est uniforme et s'effectue en transmettant la clé d'API dans l'en-tête HTTP personnalisé :
APIKEY: votre_cle_api_cutout_pro
Contrôle préalable des crédits en environnement de production
Les imports de catalogues saisonniers peuvent mobiliser des dizaines de milliers d'images par lot. Si les crédits viennent à manquer en cours de traitement, les requêtes échouent massivement avec le code d'erreur 4001 (crédits insuffisants). Le pipeline doit donc impérativement vérifier le solde du compte avant de lancer les traitements de masse.
Cutout.pro propose un point de terminaison dédié à la consultation du solde :
- Point de terminaison :
GET https://www.cutout.pro/api/v1/mySubscription - En-têtes :
APIKEY: <VOTRE_CLE_API>,Accept: application/json
Exemple de réponse JSON :
{
"code": 0,
"data": {
"monthBalance": 1250,
"imageBalance": 5000,
"videoBalance": 0,
"monthStartDate": "2026-10-01 00:00:00",
"monthExpireDate": "2026-11-01 00:00:00"
},
"msg": null,
"time": 1728729600000
}
L'ajout de ce contrôle dans l'orchestrateur de tâches permet de suspendre automatiquement les traitements et d'alerter les équipes opérationnelles en cas de solde critique.
2. Choix des points de terminaison et paramètres clés
Pour le détourage d'articles et d'objets marchands, Cutout.pro recommande le modèle mattingType=6 (détourage général d'objets, vêtements et produits) ou mattingType=1. L'API propose trois modes d'intégration selon l'infrastructure backend :
| Mode | Point de terminaison | Méthode & Content-Type | Format de réponse | Cas d'usage recommandé |
|---|---|---|---|---|
| Mode 1 : Flux binaire | https://www.cutout.pro/api/v1/matting | POST / multipart/form-data | Flux binaire brut (image/png) | Écriture directe sur disque ou traitement mémoire |
| Mode 2 : Base64 dans JSON | https://www.cutout.pro/api/v1/matting2 | POST / multipart/form-data | JSON avec data.imageBase64 | Microservices communiquant en JSON RPC |
| Mode 3 : URL d'image | https://www.cutout.pro/api/v1/mattingByUrl | GET / paramètres d'URL | JSON avec data.imageBase64 | Images déjà hébergées sur Amazon S3, Cloudflare R2 ou CDN |
Paramètres indispensables à la standardisation e-commerce
mattingType(entier, obligatoire) : Définir sur6pour le détourage de produits e-commerce.crop(booléen, facultatif) : Àtrue, l'algorithme supprime automatiquement les bordures transparentes superflues et recadre l'image au plus près de l'objet.cropMargin(chaîne, facultatif) : Utilisé conjointement aveccrop=true. Permet d'ajouter une marge autour du produit en pixels (ex."30px") ou en pourcentage (ex."10%").bgcolor(chaîne hexadécimale, facultatif) : Remplit la transparence avec une couleur unie sans préfixe#(ex.FFFFFFpour du blanc pur). La valeur spéciale'blur'génère un effet de flou d'arrière-plan.outputFormat(chaîne, facultatif) : Format de sortie souhaité (png,webpoujpg_<qualité>, par exemplejpg_85).preview(booléen, facultatif) : Àtrue, la résolution maximale est bridée à 500x500 pixels et ne consomme que 0,25 crédit par appel (contre 1 crédit pour une résolution standard jusqu'à 4096x4096px et <15 Mo). Idéal pour les prévisualisations sur les portails vendeurs.
3. Traitement par lots à grande échelle et limitation de débit
L'API de Cutout.pro fonctionne de manière synchrone : chaque connexion HTTP attend que l'inférence du serveur soit terminée pour recevoir le résultat. Cependant, la plateforme impose une limite stricte de 5 requêtes simultanées par seconde (5 QPS).
L'envoi massif de requêtes non régulées génère systématiquement le code d'erreur 5005 (Too many requests in the queue, please wait). Pour traiter des catalogues de plus de 10 000 SKU de façon résiliente, il est indispensable de structurer les appels via une file de messages asynchrone.
Architecture recommandée
[Import par lots ERP / PIM]
│ (Soumission des SKU)
▼
[Message Broker : Redis / RabbitMQ]
│
▼
[Groupe de Workers (Celery / BullMQ)]
├── Régulateur Token Bucket (Plafonné à <= 4.5 QPS)
├── Appel API Cutout.pro (POST /api/v1/matting?mattingType=6)
│ └── Backoff exponentiel en cas d'erreur 5005
├── Moteur de post-traitement local (Pillow / Sharp)
│ ├── Centrage sur canevas carré blanc (ex. 2000x2000px)
│ ├── Mise à l'échelle à 85% de la surface
│ └── Synthèse d'une ombre de contact réaliste
├── Stockage cloud (AWS S3 / Cloudflare R2)
└── Webhook vers l'ERP (Mise à jour des fiches articles)
Gestion de la résilience et des erreurs
- Régulation par Token Bucket : Implémentez un limiteur centralisé sous Redis afin que l'ensemble du cluster de workers ne dépasse jamais 4,5 QPS, évitant ainsi le rejet serveur.
- Gestion différentielle des erreurs :
5005(File d'attente saturée) : Déclencher un backoff exponentiel avec gigue aléatoire (délais de 1,5s, 3s, 6s).1002(Fichier supérieur à 15 Mo) ou5008(Image non reconnue) : Diriger l'élément vers une Dead-Letter Queue (DLQ) pour contrôle visuel dans l'ERP.4001(Crédits épuisés) : Mettre immédiatement en pause le traitement des files et alerter les équipes d'astreinte.
4. Pipeline complet de standardisation : Dimensions, marges et ombres
Même si l'API propose le paramètre bgcolor=FFFFFF, les exigences des places de marché imposent une géométrie précise :
- Un canevas rigoureusement carré (ratio 1:1, ex. 2000x2000 pixels).
- Un encombrement du produit représentant 80% à 85% de la surface de l'image.
- Un détourage brut sur fond blanc crée une impression d'autocollant artificiel. L'ajout d'une ombre de contact douce à la base de l'objet rétablit le réalisme et la perspective.
La bonne pratique consiste à demander à Cutout.pro un PNG transparent détouré (crop=true, sans bgcolor), puis à appliquer la composition du canevas et la synthèse de l'ombre au niveau du worker local via des bibliothèques telles que Python Pillow ou Node.js Sharp.
Implémentation en Python avec Pillow
import io
import time
import requests
from PIL import Image, ImageFilter
CUTOUT_API_KEY = "VOTRE_CLE_API_ICI"
API_URL = "https://www.cutout.pro/api/v1/matting?mattingType=6&crop=true"
def remove_background(image_bytes: bytes, max_retries: int = 3) -> bytes:
"""Appelle Cutout.pro avec backoff exponentiel pour respecter la limite de débit."""
headers = {"APIKEY": CUTOUT_API_KEY}
files = {"file": ("product.jpg", image_bytes, "image/jpeg")}
for attempt in range(max_retries):
response = requests.post(API_URL, headers=headers, files=files, timeout=30)
if response.status_code == 200 and response.headers.get("Content-Type", "").startswith("image/"):
return response.content
try:
err = response.json()
code = err.get("code")
msg = err.get("msg")
if code == 5005: # Limite de débit atteinte
time.sleep((2 ** attempt) + 0.5)
continue
elif code == 4001:
raise RuntimeError("Crédits Cutout.pro épuisés.")
else:
raise ValueError(f"Erreur Cutout.pro : {code} - {msg}")
except requests.exceptions.JSONDecodeError:
response.raise_for_status()
raise TimeoutError("Nombre maximal de tentatives dépassé pour Cutout.pro.")
def standardize_product_image(
transparent_png_bytes: bytes,
target_canvas_size: int = 2000,
fill_ratio: float = 0.85
) -> Image.Image:
"""
Standardise l'image sur un canevas carré blanc pur, ajuste l'échelle à 85%
et génère une ombre de contact naturelle au sol.
"""
# 1. Chargement du détourage transparent
product = Image.open(io.BytesIO(transparent_png_bytes)).convert("RGBA")
prod_w, prod_h = product.size
# 2. Mise à l'échelle homothétique selon le ratio cible
max_dim = int(target_canvas_size * fill_ratio)
scale = min(max_dim / prod_w, max_dim / prod_h)
new_w, new_h = int(prod_w * scale), int(prod_h * scale)
product_resized = product.resize((new_w, new_h), Image.Resampling.LANCZOS)
# 3. Création du canevas blanc carré
canvas = Image.new("RGBA", (target_canvas_size, target_canvas_size), (255, 255, 255, 255))
# 4. Synthèse de l'ombre de contact douce
alpha_mask = product_resized.split()[3]
shadow_height = max(10, int(new_h * 0.08))
# Compression verticale du masque alpha pour créer l'empreinte au sol
shadow_footprint = alpha_mask.resize((new_w, shadow_height), Image.Resampling.BILINEAR)
shadow_footprint = shadow_footprint.filter(ImageFilter.GaussianBlur(radius=15))
# Calque gris foncé semi-transparent avec opacité à 35%
shadow_layer = Image.new("RGBA", (new_w, shadow_height), (40, 40, 40, 0))
shadow_layer.putalpha(shadow_footprint.point(lambda p: int(p * 0.35)))
# 5. Positionnement des éléments sur le canevas
pos_x = (target_canvas_size - new_w) // 2
pos_y = (target_canvas_size - new_h) // 2
# Insertion de l'ombre au niveau de la base du produit
shadow_y = pos_y + new_h - int(shadow_height * 0.6)
canvas.paste(shadow_layer, (pos_x, shadow_y), shadow_layer)
# Superposition du produit détouré
canvas.paste(product_resized, (pos_x, pos_y), product_resized)
# Conversion finale en RGB pour exportation standard
return canvas.convert("RGB")
def process_sku(raw_path: str, output_path: str):
with open(raw_path, "rb") as f:
raw_bytes = f.read()
# Étape 1 : Détourage distant via l'API
cutout_bytes = remove_background(raw_bytes)
# Étape 2 : Cadrage local et rendu de l'ombre
final_img = standardize_product_image(cutout_bytes)
# Étape 3 : Sauvegarde en JPEG optimisé
final_img.save(output_path, "JPEG", quality=90, optimize=True)
5. Bonnes pratiques et optimisation des coûts
- Privilégier
mattingByUrlpour préserver la bande passante : Lorsque les visuels bruts sont déjà hébergés sur AWS S3 ou un CDN, utilisez le modemattingByUrlen transmettant l'URL publique. Cela évite le téléchargement puis le renvoi de fichiers volumineux depuis vos serveurs applicatifs. - Flux d'approbation en deux temps : Utilisez le mode
preview=true(0,25 crédit) pour les épreuves de contrôle ou la phase de brouillon. Dès que le produit est validé pour publication définitive, lancez l'appel en haute résolution (1 crédit). - Archivage des masques PNG transparents : Conservez les fichiers PNG transparents originaux fournis par Cutout.pro dans un stockage froid. Si les règles graphiques de votre boutique évoluent ultérieurement (changement de couleur de fond ou de marges), vous pourrez régénérer l'ensemble du catalogue localement sans dépenser de nouveaux crédits API.