← retour aux projets

CS.01, CASE STUDY · CÔTÉ SYSTÈME

PIXANOOV

Hoortrade

|←PACK EIGER 350B160 · GÉNÉRÉ EN 1 CLIC→|
|←DÉTOURAGE AUTO · BUNKER B500→|
|←DÉTOURAGE AUTO · EIFEL 15H166→|
|←PACK VOGEL 350B160 · SORTIE PIPELINE→|

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.

Portillon FOLYA détouré automatiquement, fond transparentPortillon RUIVO détouré automatiquement, fond transparentVue trois-quarts du portillon FOLYA détourée automatiquementVue du portillon RUIVO 100P160 détourée automatiquementDétourage automatique d'une motorisation BUNKER, présentation cercleDétourage automatique d'un accessoire EIFEL aluminium gris1 / 6
|←SORTIE PIPELINE · FOLYA 100P140 DÉTOURÉ→|
scripts_generes/detourage_detourage.jsxjavascript
var 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)
};
Le pont Python → Adobe en une image : l'UI web écrit ce CONFIG, Photoshop l'exécute.

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.

Schéma technique coté du portail coulissant FOLYA généré via PIXANOOVSchéma technique coté du portillon FOLYA 100P140Schéma technique du portail coulissant NALI VELETA, charte noireSchéma technique des poteaux aluminium1 / 4
|←SORTIE PIPELINE · SCHÉMA FOLYA 400C160→|
webapp/app.pypython
def 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'
Extraction de cotes par IA multimodale : la page PDF est rendue en 200 dpi puis envoyée à Gemini Vision.

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.

analyser_image_portail.pypython
# 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.1
Détection de la bounding box du vantail : les piliers montent plus haut et descendent plus bas, les percentiles les écartent.

04 · 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é.

Pack composé automatiquement : portail battant RUIVO et kit de motorisationPack composé automatiquement : portail battant RUIVO et portillon assortiPack composé automatiquement : portillon RUIVO et deux poteaux aluminiumPack produit EIGER généré automatiquement, vues multiples assemblées1 / 4
|←SORTIE PIPELINE · PACK RUIVO + MOTORISATION→|
generer_packs.jsxjavascript
// 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];
Placement d'un produit dans son slot, dans le repère inversé d'Illustrator : fit proportionnel, centrage, bas aligné sur l'ancre.

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.

Portail battant intégré par IA dans un décor pavillonnaire réalistePortail coulissant intégré par IA dans son environnementPortillon intégré par IA dans un décor réaliste1 / 3
|←MISE EN SITUATION IA · PORTAIL BATTANT→|

LA FACE VISIBLE, CÔTÉ STUDIO