API REST d'essayage virtuel : à partir d'une photo de personne et d'une photo de vêtement, l'API génère une image de la personne portant le vêtement.
Document destiné aux équipes techniques des marques pour évaluer une intégration dans une application mobile ou un site e-commerce.
| Style | REST, multipart/form-data |
| Entrées | 2 images (personne, vêtement) + paramètres optionnels |
| Sortie | Image PNG (768 × 1024) |
| Latence | ~20–60 s par génération (démo) |
| Documentation interactive | GET /docs (Swagger UI généré automatiquement) |
Architecture : l'API est un service HTTP autonome. Une application (Zara, H&M, app de boutique…) l'appelle côté serveur : l'app envoie les deux photos, reçoit l'URL de l'image générée, l'affiche au client. Aucune installation côté client, aucun matériel en magasin.
GET /v1/healthVérification de disponibilité.
Réponse 200
{ "status": "ok", "engine": "idm-vton (démo)", "version": "0.1.0-demo" }
POST /v1/try-onGénère un essayage.
Requête — multipart/form-data
| Champ | Type | Obligatoire | Description |
|---|---|---|---|
person_image |
fichier image | oui | Photo de la personne. Debout, corps visible, fond uni = meilleurs résultats. Max 10 Mo. |
garment_image |
fichier image | oui | Photo du vêtement seul (à plat, sur cintre ou packshot produit). Max 10 Mo. |
category |
tops | bottoms | one-pieces |
non | Type de vêtement : haut, bas (pantalon/jupe/short) ou tenue complète (robe, combinaison). Défaut tops. |
garment_description |
texte | non | Description courte, ex. t-shirt blanc à col V. Améliore la fidélité. |
denoise_steps |
entier 10–50 | non | Qualité du rendu. Défaut 30. Plus haut = plus fin mais plus lent. |
seed |
entier | non | Graine aléatoire. Même seed + mêmes images = même résultat (tests A/B, reproductibilité). |
Réponse 200
{
"job_id": "a1b2c3d4e5f6",
"status": "succeeded",
"result_image_url": "/results/a1b2c3d4e5f6.png",
"processing_time_ms": 21000
}
Erreurs
| Code | Signification |
|---|---|
| 413 | Image trop lourde (> 10 Mo) |
| 422 | Champ manquant ou invalide |
| 502 | Le moteur de génération a échoué (réessayer) |
POST /v1/product-from-linkRécupère les informations d'un produit à partir d'un lien marchand : nom, prix et photo du vêtement (prête pour /v1/try-on).
Body JSON : { "url": "https://..." }
Réponse 200
{
"status": "ok", // ou "blocked" / "error"
"name": "Kith Adrian Tee - White",
"price": "70.0 USD",
"image_base64": "...", // photo packshot du produit
"image_mime": "image/jpeg",
"source_url": "https://..."
}
Limites : la majorité des grandes enseignes (Zara, H&M, Sézane...) bloque la lecture automatique par anti-bot ; l'API renvoie alors status: "blocked" et l'intégration doit proposer l'envoi d'une photo/capture du vêtement en repli. Les dimensions exactes des vêtements ne sont publiées par aucune enseigne : la suggestion de taille (V2) s'appuiera sur les guides des tailles et les mensurations du client. En intégration native dans l'app de la marque, ces limites disparaissent — la marque fournit directement photo et fiche produit.
POST /v1/size-recommendationRecommande la taille à prendre chez une marque à partir des mensurations du client. Grilles = mensurations du corps publiées par les marques (Zara, H&M) — les dimensions des vêtements ne sont pas publiées.
Body JSON : { "brand": "zara", "category": "tops|bottoms", "chest_cm": 96, "waist_cm": 84, "hips_cm": 98, "fit": "confort|ajuste" }
Réponse 200
{
"status": "ok",
"brand_label": "Zara",
"recommended_size": "M",
"rationale": "Avec 96 cm de poitrine, la grille Zara place la taille M (94-98 cm).",
"note": "Zara taille plutôt petit...",
"source": "https://sizecharter.com/brands/zar/mens"
}
Logique : la mesure principale (poitrine pour les hauts, taille pour les bas) place la taille ; la mesure secondaire (taille / hanches) la fait remonter si nécessaire ; la préférence de coupe ajuste en bord de fourchette. Sources des grilles : H&M (tableau officiel hm.com), Zara (sizecharter.com, pouces convertis).
GET /results/{job_id}.pngTélécharge l'image générée (PNG 768 × 1024).
async function essayageVirtuel(photoClient, photoArticle) {
const form = new FormData();
form.append("person_image", photoClient); // File ou Blob
form.append("garment_image", photoArticle); // File ou Blob
form.append("garment_description", "robe bleue");
const r = await fetch("https://api.fiffingroom.example/v1/try-on", {
method: "POST", body: form
});
const { result_image_url } = await r.json();
return "https://api.fiffingroom.example" + result_image_url;
}
curl -X POST https://api.fiffingroom.example/v1/try-on \
-F "person_image=@cliente.jpg" \
-F "garment_image=@robe.jpg" \
-F "garment_description=robe bleue"
import requests
with open("cliente.jpg", "rb") as p, open("robe.jpg", "rb") as g:
r = requests.post("https://api.fiffingroom.example/v1/try-on",
files={"person_image": p, "garment_image": g},
data={"garment_description": "robe bleue"})
print(r.json()["result_image_url"])
category.seed pour un rendu déterministe).| Sujet | Démo (aujourd'hui) | Production (cible) |
|---|---|---|
| Moteur | Space Hugging Face public gratuit (IDM-VTON) | Modèle auto-hébergé sur GPU dédié, ou licence commerciale |
| Latence | 20–60 s (file d'attente partagée) | 5–15 s (GPU réservé) |
| Disponibilité | best effort, sans SLA | SLA 99,9 %, autoscaling |
| Licence modèle | CC-BY-NC (usage non commercial) | Licence commerciale à négocier ou modèle alternatif |
| Sécurité | CORS ouvert, pas d'authentification | Clés API par marque, CORS restreint, HTTPS |
| Données | Les photos transitent par le Space public | Traitement privé, conformité RGPD, suppression automatique |
Points à traiter avant tout contrat de marque : licence commerciale du modèle, hébergement GPU (coût ~0,5–1 €/h), authentification par clé API, et politique de conservation des photos (RGPD — les photos de clients sont des données personnelles).
Direction produit envisagée : en complément de l'essayage sur photo réelle, permettre à l'utilisateur de créer un avatar personnel à partir de ses mensurations (taille, corpulence, morphologie), réutilisable sur toutes les boutiques partenaires sans reprendre de photo.
Pistes techniques : génération d'un mannequin synthétique cohérent (photo de référence + paramètres corporels), ou modèle 3D paramétrique (type SMPL) rendu en image puis passé au moteur d'essayage. Avantage clé : une seule saisie des mensurations pour toutes les marques intégrant l'API, et des recommandations de taille en plus du rendu visuel.
Impact API prévu : POST /v1/avatars (création d'avatar), avatar_id en
remplacement de person_image dans /v1/try-on.