CONTEXTE
Hoortrade sort plus de 300 nouvelles références par an (portails, pergolas, clôtures en kit). Toute la production de visuels se faisait à la main, sous Photoshop et Illustrator : détourages, schémas cotés, packs. Lent, répétitif, plein d'erreurs.
MON RÔLE
Conception et développement de bout en bout, seul : webapp de pilotage, génération dynamique de scripts Adobe, extraction de cotes par IA, analyse d'image. L'endroit exact où mes deux métiers se rejoignent : c'est un œil de graphiste qui a écrit ces pipelines.
RÉALISATIONS
- Architecture originale : le backend Flask génère des scripts ExtendScript (.jsx) à la volée puis pilote Photoshop et Illustrator en ligne de commande
- 5 modules de production automatisée, chacun avec un gain mesuré (détail ci-dessous)
- Extraction de cotes PDF par Gemini Vision avec fallback OCR Tesseract
- Packagé en .exe distribuable (PyInstaller + Nuitka) ; roadmap serveur multi-utilisateurs cadrée
CHIFFRES
43 routes API · 5 modules · ×12 détourage · ×300 packs · 25-35 k€/an économisés
OUTILS
- Python
- Flask
- Pillow
- PyMuPDF
- Gemini Vision
- ExtendScript (JSX)
- PyInstaller
CS.01.M, LES MODULES, PIÈCE PAR PIÈCE
Sous le capot
01 · Détourage automatique
×12 : 2 h ramenées à 10 min par référence (~10 images)
L'interface web sérialise les paramètres du graphiste dans un objet CONFIG en tête d'un script Photoshop généré, qui enchaîne suppression du fond, retouches, redimensionnement entre guides et exports PNG/JPG aux formats site et marketplaces. Trois modes selon la matière du produit.





1 / 6var CONFIG = {
REFERENCE: "COULISSANTS Art C-S",
PORTAIL_TYPE: "fonce",
DETOURAGE_MODE: "detourage",
IS_PERGOLA: false,
PSD_FOLDER_NAME: "PSD",
IGNORE_FOLDERS: ["OUTPUT", "PSD", "PNG", "PNG_Detoures",
"output", "PNG_OMBRE", "PSD_OMBRE", "RENDU"],
VALID_EXTENSIONS: ["jpg", "jpeg", "png", "tif", "tiff", "psd", "bmp"],
WHITE_THRESHOLD: 240,
TOLERANCE: 10 // Tolerance detourage (configurable depuis l'interface)
};02 · Schémas techniques cotés
3 jours → 1 jour par gamme complète
Le module lit la notice PDF du produit, envoie la page de schéma à Gemini Vision pour en extraire les cotes (fallback OCR), analyse le PNG détouré pour localiser le vantail, puis génère un script Illustrator qui place cotations, flèches et pictos sur le template de la gamme.



1 / 4def extraire_cotes_gemini(chemin_pdf, api_key, type_produit=''):
"""Extrait les cotes d'un PDF en envoyant la page schema a Gemini Vision."""
doc = fitz.open(chemin_pdf)
page_index = 1 if len(doc) >= 2 else 0
page = doc[page_index]
# Rendre la page en image HD
pix = page.get_pixmap(dpi=200)
img_bytes = pix.tobytes("png")
doc.close()
image_b64 = base64.b64encode(img_bytes).decode()
# Deduire le type si pas fourni
if not type_produit:
chemin_upper = chemin_pdf.upper()
if 'BATTANT' in chemin_upper:
type_produit = 'B'
elif 'COULISSANT' in chemin_upper:
type_produit = 'C'
elif 'PORTILLON' in chemin_upper:
type_produit = 'P'03 · Analyse d'image sans ML
Pour placer les cotes au bon endroit, il faut distinguer le vantail des piliers sur le PNG détouré. Plutôt qu'un modèle entraîné : un balayage de colonnes de pixels et un filtrage statistique par percentiles 25-75 qui exclut naturellement les extrêmes. Du traitement d'image au raisonnement simple, rapide et déterministe.
# Utiliser le percentile 25-75 pour exclure les extremes (piliers)
idx_25 = len(valeurs_haut) // 4
idx_75 = 3 * len(valeurs_haut) // 4
if idx_75 > idx_25:
# Prendre les valeurs du vantail (zone centrale)
haut_portail = valeurs_haut[idx_25] # exclut piliers qui montent plus haut
bas_portail = valeurs_bas[idx_75] # exclut piliers qui descendent plus bas
else:
# Pas assez de donnees, utiliser les medianes
haut_portail = valeurs_haut[len(valeurs_haut) // 2]
bas_portail = valeurs_bas[len(valeurs_bas) // 2]
# Colonnes du vantail : haut/bas proches de la mediane, a 10% pres
tolerance = hauteur * 0.104 · Packs produit
×300 : 3-4 jours ramenés à 10 min pour 250 références
Quatorze compositions de packs (portail + portillon + accessoires) déclarées en données puis instanciées en artboards Illustrator : zones, ancres et labels. En batch, une liste brute de 250 références est parsée, analysée en streaming, les images copiées depuis le réseau et le script de composition généré.



1 / 4// Calculer le facteur d'echelle pour tenir dans la zone
var scaleX = zoneBounds.width / imgLargeur;
var scaleY = zoneBounds.height / imgHauteur;
var scale = Math.min(scaleX, scaleY); // ne pas depasser
placedItem.resize(scale * 100, scale * 100);
var nouvelleLargeur = placedItem.width;
var nouvelleHauteur = placedItem.height;
// Centree horizontalement, bas de l'image aligne sur l'ancre
var centreZoneX = zoneBounds.left + zoneBounds.width / 2;
var imgX = centreZoneX - nouvelleLargeur / 2;
var imgY = ancreY + nouvelleHauteur; // Y en Illustrator = haut de l'objet
placedItem.position = [imgX, imgY];05 · Publication & mise en situation IA
Un module scanne, trie et renomme les images finales par catégorie (rendus, schémas, zooms) avec préfixes normalisés site et marketplaces. Le dernier module industrialise la mise en situation par IA générative : décors réalistes autour du produit détouré, un travail que je faisais manuellement comme infographiste.


1 / 3LA FACE VISIBLE, CÔTÉ STUDIO