Catégorie : Projets

  • Mesurer le taux d’encrage : pourquoi la mesure “au point” ne suffit pas, et comment obtenir une mesure globale exploitable

    Quand on parle d’éco-conception graphique, on finit toujours par se heurter à un sujet très concret : combien d’encre met-on réellement sur une surface ? Sur du packaging, l’enjeu est donc double : d’une part, il faut composer avec des contraintes techniques telles que le séchage, la surcharge ou les procédés. D’autre part, s’ajoutent désormais des objectifs liés à la sobriété et à la réduction de l’empreinte environnementale.

    Dans le guide fourni par CITEO au sujet de l’éco-encrage, le “taux d’encrage” est défini comme la somme des pourcentages de couverture des encres (CMJN et/ou tons directs) sur un échantillon donné.
    C’est une base utile. En revanche, la question centrale reste entière : comment le mesurer de manière fiable et reproductible sur un document complet ?

    Constat 1 : certains outils semblent difficiles à trouver aujourd’hui

    Le guide cite notamment un outil lié à Diadeis. De mon côté, au moment d’écrire ces lignes, je n’ai pas trouvé de moyen d’y accéder / de le retrouver opérationnel (si vous l’avez, je prends l’info 😊). Plutôt que de dépendre d’un outil inaccessible, j’ai cherché une méthode reproductible, documentée et automatisable, basée sur des briques standard.

    Constat 2 : la mesure “en un point” n’est pas une mesure globale

    L’autre approche souvent proposée consiste à mesurer le taux d’encrage à un endroit précis (avec des outils de type pipette, aperçu séparations, ou lecture d’un point). Le guide présente d’ailleurs ce type de démarche via des outils courants (Adobe Photoshop), en illustrant une lecture ponctuelle.

    Le souci n’est pas que cette mesure soit “fausse”. Le souci est qu’elle répond à une autre question.

    • Une mesure au point répond à : “à cet endroit, quelle est la couverture CMJN/spot ?”
    • Une mesure globale répond à : “sur toute la surface du document, quelle quantité d’encre est demandée en moyenne ?”

    Et ce glissement est important : un packaging n’est pas uniforme. Entre le fond, les images, les textes, les pictos, les codes-barres… une mesure ponctuelle peut être très différente de la réalité moyenne du document.

    Ce qui manque souvent : la mesure globale “par couche”

    Là où je pense qu’il manque une marche, c’est l’idée suivante :

    mesurer pour chaque encre (CMJN + tons directs) la couverture moyenne sur l’ensemble de la surface, puis en déduire un indicateur global.

    C’est particulièrement important en packaging parce qu’il y a fréquemment :

    • des tons directs (Pantone, blanc de soutien, vernis, …)
    • et ces couches peuvent peser très lourd dans l’encrage global

    Si on ne mesure que CMJN, on peut sous-estimer la charge d’encrage de façon significative.


    Une proposition constructive : une mesure globale, reproductible, indépendante du RIP imprimeur

    L’objectif ici n’est pas de “remplacer” les méthodes existantes, mais de proposer un complément plus mesurable, surtout si on veut comparer des versions de design (V1 vs V2, avant/après optimisation).

    L’idée en une phrase

    1. On transforme le PDF en séparations contone (ton continu) : une image par encre, sans trame.
    2. On calcule la moyenne de chaque séparation → couverture moyenne de l’encre.
    3. On somme les couvertures moyennes → TAC moyen (Total Area Coverage moyen).

    Le TAC (Total Area Coverage) correspond à la somme des couvertures des encres superposées. Le guide définit d’ailleurs le taux d’encrage comme une somme de couvertures, ce qui rejoint naturellement cette logique, à condition de la faire sur toute la surface plutôt qu’en un point.

    Méthode décomposée en étapes

    Étape 1 — Partir d’un PDF print final

    PDF/X-4 ou équivalent : c’est le document prêt-à-imprimer.

    Étape 2 — Rasteriser en séparations contone

    On utilise Ghostscript (une brique open-source) pour générer :

    • une image par encre (CMJN + tons directs)
    • en niveaux de gris (ton continu), avant tramage

    En pratique, cela produit des fichiers du type :

    • separations_1(Cyan).tif
    • separations_1(PANTONE 485 C).tif
    • etc.

    À cette étape, cela revient au même d’ouvrir le PDF dans Photoshop et d’enregistrer chaque couche séparément.

    Étape 3 — Calculer la couverture moyenne par encre

    Chaque séparation est une “carte” de l’encre :

    • 0% = pas d’encre
    • 100% = encre pleine

    On calcule la moyenne de l’image :

    • Couverture moyenne (%) = moyenne(pixel) / max(pixel) × 100

    Étape 4 — Calculer un indicateur global

    Pour une page :

    • TAC moyen = C + M + J + N + Spots

    Cela donne un chiffre simple qui permet :

    • de comparer deux versions,
    • d’objectiver une optimisation,

    Automatisation : du protocole au programme

    Afin de mettre en place rapidement et facilement cette logique, nous allons utiliser un ensemble d’outils et langages multiplateforme (et avec la formidable aide de ChatGPT 🤫).

    Ghostscript

    Ghostscript est un interpréteur open-source de formats graphiques standard (PDF, PostScript, EPS).
    Dans ce projet, il est utilisé comme un véritable moteur de prépresse : il transforme un PDF en séparations couleur en ton continu (une image par encre, sans tramage). C’est cette étape qui permet de passer d’un document vectoriel abstrait à des données mesurables, exploitables pour un calcul objectif du taux d’encrage.

    ImageMagick

    ImageMagick est une suite d’outils open-source dédiée à la manipulation et à l’analyse d’images.
    Il est utilisé ici principalement comme outil de contrôle et de diagnostic : ouverture des séparations, inspection des valeurs min/max/moyenne, vérification visuelle du contenu des couches. Il permet de valider rapidement que les images générées sont cohérentes avant toute analyse automatisée.

    Python

    Python est un langage de programmation open-source orienté lisibilité et prototypage rapide.
    Il sert ici de “colle” entre les différents outils : orchestration de Ghostscript, lecture des images, calcul des indicateurs, et export des résultats sous forme de tableau (CSV). L’intérêt principal est la reproductibilité : une fois le script validé, l’analyse peut être rejouée à l’identique sur n’importe quel document.

    Bibliothèques Python utilisées

    Pillow

    Pillow est une bibliothèque de lecture et de traitement d’images. Elle permet d’ouvrir les fichiers TIFF générés par Ghostscript et d’accéder directement aux valeurs de pixels.

    NumPy

    NumPy est une bibliothèque de calcul numérique. Elle est utilisée pour manipuler les images sous forme de tableaux et calculer des statistiques simples (moyenne, min, max) de manière fiable et performante.

    Pandas

    Pandas est une bibliothèque de manipulation de données tabulaires. Elle sert à structurer les résultats (par page et par encre) et à produire un fichier CSV facilement exploitable dans Excel, LibreOffice ou des outils de visualisation comme Power BI.

    import argparse
    import subprocess
    import tempfile
    import os
    import re
    from pathlib import Path
    
    import numpy as np
    import pandas as pd
    from PIL import Image
    
    
    def trouverGhostscript():
        """
        Retourne le nom du binaire Ghostscript selon l'OS.
        - Windows : gswin64c.exe
        - Linux/Mac : gs
        """
        if os.name == "nt":
            return "gswin64c"
        return "gs"
    
    
    def executerGhostscript(cheminPdf, resolutionDpi, dossierSortie):
        """
        Lance Ghostscript pour générer les séparations contone.
    
        Paramètres :
        - cheminPdf : PDF d'entrée
        - resolutionDpi : résolution de rasterisation
        - dossierSortie : dossier temporaire de sortie
        """
        gs = trouverGhostscript()
    
        # Pattern de sortie :
        # %d = numéro de page
        # Ghostscript ajoutera (NomEncre) automatiquement
        sortie = str(dossierSortie / "separations_%d.tif")
    
        commande = [
            gs,
    
            # Sécurité : empêche l'exécution de code dangereux dans le PDF
            "-dSAFER",
    
            # Mode batch : quitte automatiquement après traitement
            "-dBATCH",
    
            # Pas de pause entre les pages
            "-dNOPAUSE",
    
            # Device spécial : génère une image par séparation couleur
            "-sDEVICE=tiffsep",
    
            # Résolution de travail (DPI)
            # Plus c'est élevé, plus la mesure est précise (au prix du temps)
            f"-r{resolutionDpi}",
    
            # Fichier de sortie (pattern)
            f"-sOutputFile={sortie}",
    
            # PDF source
            str(cheminPdf)
        ]
    
        subprocess.run(commande, check=True)
    
    
    def calculerCouverture(cheminTiff, noInvert):
        """
        Calcule la couverture moyenne (%) d'une séparation.
    
        Par défaut (logique Ghostscript) :
        - noir = encre
        - blanc = pas d'encre
    
        Donc :
        couverture = (1 - moyenne_normalisée) * 100
        """
        image = Image.open(cheminTiff).convert("L")
        pixels = np.array(image)
    
        # Valeur maximale théorique du format (255 en 8 bits, 65535 en 16 bits)
        maxTheorique = np.iinfo(pixels.dtype).max
    
        # Moyenne normalisée entre 0 et 1
        moyenne = pixels.mean() / maxTheorique
    
        # Contrôle qualité : fond non nul (séparation polluée)
        if pixels.min() > 0:
            print("⚠️ Attention : fond non nul détecté dans", cheminTiff.name)
    
        # Par défaut : inversion (noir = encre)
        if noInvert:
            # Mode debug : blanc = encre
            couverture = moyenne * 100.0
        else:
            # Mode normal : noir = encre
            couverture = (1.0 - moyenne) * 100.0
    
        return float(couverture)
    
    
    def analyserSeparations(dossier, noInvert):
        """
        Analyse toutes les séparations générées par Ghostscript.
        Retourne un DataFrame pandas.
        """
        # Regex pour extraire :
        # separations_1(Cyan).tif → page=1, encre=Cyan
        motif = re.compile(r"separations_(\d+)\((.+)\)\.tif")
        resultats = {}
    
        for fichier in dossier.glob("separations_*.tif"):
            match = motif.match(fichier.name)
            if not match:
                continue
    
            page = int(match.group(1))
            encre = match.group(2)
    
            couverture = calculerCouverture(fichier, noInvert)
    
            if page not in resultats:
                resultats[page] = {}
    
            resultats[page][encre] = couverture
    
        # Construction du tableau final
        lignes = []
    
        for page, encres in sorted(resultats.items()):
            for encre, valeur in sorted(encres.items()):
                lignes.append({
                    "Page": page,
                    "Encre": encre,
                    "Couverture_%": round(valeur, 2)
                })
    
            # TAC moyen = somme de toutes les encres
            tac = sum(encres.values())
            lignes.append({
                "Page": page,
                "Encre": "TAC_MOYEN",
                "Couverture_%": round(tac, 2)
            })
    
        return pd.DataFrame(lignes)
    
    
    def main():
        """
        Point d'entrée CLI.
        """
        parser = argparse.ArgumentParser(
            description="Analyse du taux d'encrage contone depuis un PDF (CMJN + tons directs)"
        )
    
        # PDF source
        parser.add_argument(
            "-f", "--fichier",
            required=True,
            help="PDF à analyser"
        )
    
        # Résolution de rasterisation
        parser.add_argument(
            "-r", "--resolution",
            type=int,
            default=600,
            help="Résolution DPI (défaut 600)"
        )
    
        # Option debug : désactive l'inversion
        parser.add_argument(
            "--no-invert",
            action="store_true",
            help="Désactive l'inversion (rarement utile, debug seulement)"
        )
    
        args = parser.parse_args()
    
        cheminPdf = Path(args.fichier).resolve()
        if not cheminPdf.exists():
            raise FileNotFoundError("PDF introuvable")
    
        # Dossier temporaire auto-nettoyé
        with tempfile.TemporaryDirectory() as tmp:
            dossierTmp = Path(tmp)
    
            print("Rasterisation via Ghostscript...")
            executerGhostscript(cheminPdf, args.resolution, dossierTmp)
    
            print("Analyse des séparations...")
            df = analyserSeparations(dossierTmp, noInvert=args.no_invert)
    
            # Nom du CSV basé sur le PDF
            nomCsv = f"couverture_encres_{cheminPdf.stem}.csv"
            df.to_csv(nomCsv, index=False)
    
            print("\nRésultats :")
            print(df)
            print(f"\nCSV généré : {nomCsv}")
    
    
    if __name__ == "__main__":
        main()
    

    Ensuite, il suffit de se servir de la ligne de commande pour appeler le script et fournir en paramètre le fichier et la résolution souhaitée pour analyser avec plus ou moins de finesse le TAC moyen de toutes les encres.

    python analyse_encrage.py -f mon_packaging.pdf -r 600

    Dans cet exemple, j’utilise 600dpi en résolution de conversion, le but est d’avoir un bon compromis entre la finesse des détails vectoriels (typographies, filets) tout en gardant une valeur proche de la résolution des images et en gardant un temps de calcul raisonnable.

    TypeRésolution courante
    Web7296 dpi/ppp
    Photo300 dpi/ppp
    Vecteur/Typographie/Aplat2540 dpi/ppp

    On observe ici que les tons direct/spots sont pris en compte dans le calcul, il conviendra de les ignorer si ces encres concernent (comme ici) des repères de rainage, de coupe ou de marge de sécurité 😉.

    Pour aller plus loin et simplifier le process, on demande un coup de pouce à Claude pour obtenir un petit programme avec une interface graphique :

    • l’utilisateur choisit un PDF
    • il indique une résolution de travail
    • le programme génère les séparations
    • calcule les couvertures moyennes
    • exporte un CSV exploitable dans Excel

    L’intérêt n’est pas seulement le confort : c’est surtout la reproductibilité. On peut rejouer l’analyse à l’identique, versionner les résultats, et intégrer ça à un flux d’éco-conception.

    Conclusion

    La mesure “au point” reste utile pour diagnostiquer une zone précise (par exemple une surcharge locale pouvant causer du maculage par superposition).

    Mais si l’objectif est de parler d’éco-encrage et de comparer des designs, il est utile de disposer d’un indicateur global, calculé de façon objective sur la surface entière, et qui inclut toutes les encres, y compris les tons directs. Cette méthode est un outil complémentaire dans une démarche d’éco-conception.

    Pour les actions d’optimisations, le guide de CITEO présente des exemples réels par remplacement de benday CMJN par des tons directs (suppression d’une couche) ou une présence accrue de réserve blanche (augmentation du corps typographique en réserve). Le guide est très bien fait et permet aussi d’estimer l’épaisseur et le poids d’encre selon le procédé d’impression. Il est rédigé par Fabrice Peltier et édité par CITEO.

  • 📸 À la découverte du Maroilles AOP : immersion en Thiérache, entre terroir et traditions

    Fromage Maroilles AOP tenu entre deux mains, mettant en valeur sa croûte orangée caractéristique et son affinage artisanal.

    Le Maroilles, ses acteurs et son AOP

    À l’été 2021, le Syndicat du Maroilles AOP me missionne sur la réalisation d’un reportage photos autour du fromage, ses producteurs, ses fermes, laiteries, industries, ses produits dérivés (la boulette d’Avesnes, tartes) mais aussi de son territoire, ses prés et bocages pour alimenter ses supports de communications print et web. Retour en image sur 3 journées à la découverte de la Thiérache, à observer et capter les différentes étapes de la fabrication de ce mes, du prés à nos assiettes, à rencontrer sa confrérie et ses codes.

    Découverte du territoire

    Au cœur de l’AOP Maroilles

    Aux confins de l’Aisne et du Nord, s’étend un territoire à l’identité forte. Un pays où les haies forment un labyrinthe naturel, découpant les prairies en un patchwork vert et vallonné. C’est la Thiérache. Une terre préservée, façonnée par des siècles d’agriculture et de traditions.

    Dans ce paysage, le temps semble s’écouler différemment. Les villages s’égrènent le long des routes sinueuses, leurs clochers trapus veillant sur les fermes éparses. Ici, les prairies sont plus qu’un décor : elles sont l’âme du terroir. Elles nourrissent un cheptel précieux, garant d’un savoir-faire ancestral, d’une tradition qui a traversé les âges : celle du Maroilles AOP.

    Paysage rural de Thiérache avec un troupeau de vaches dans un pré verdoyant, garantissant un lait riche pour la fabrication du Maroilles AOP.
    Les pâturages de Thiérache, source d’un lait de qualité pour le Maroilles.
    Vue sur l’église fortifiée de Parfondeval, exemple du patrimoine historique et architectural unique de la Thiérache.
    Église fortifiée de Parfondeval, un joyau architectural de la Thiérache.
    Paysage vallonné de Thiérache avec ses haies bocagères, offrant un cadre idéal pour l’élevage des vaches laitières du Maroilles AOP.
    Le bocage de Thiérache, un écrin naturel pour l’élevage laitier.

    Un bocage vivant, un relief façonné par l’élevage

    Les pâturages de la Thiérache sont bordés de haies épaisses, vestiges d’une époque où elles servaient à protéger les cultures et à contenir le bétail. Elles offrent aujourd’hui un refuge à une biodiversité riche et préservent l’équilibre fragile de ces terres agricoles. Entre champs et vallons, l’œil s’arrête sur ces fermes typiques, aux briques rouges et aux toits pentus. Certaines sont là depuis des siècles et rivalisant presque avec les églises fortifiées.

    Membres de la Confrérie du Maroilles en habits traditionnels, célébrant la culture et l’héritage du fromage Maroilles AOP.
    La Confrérie du Maroilles, ambassadeur du fromage emblématique du Nord.
    Médaillon doré de la Confrérie du Maroilles AOP, symbole de l’héritage et de la tradition fromagère en Thiérache.
    Médaillon de la confrérie du Maroilles, gardienne du savoir-faire traditionnel.

    L’histoire d’un fromage millénaire

    Le Maroilles trouve son origine il y a plus de 1000 ans, dans l’abbaye du même nom. Les moines, mirent au point un affinage long, en cave humide. Au fil du temps, ce simple fromage frais devint un produit de caractère, reconnaissable entre mille par sa croûte orangée et son parfum puissant.

    Dans une ferme familiale, au plus près du Maroilles fermier

    Derrière les murs de briques, une ferme typique se dévoile. C’est ici que débute le véritable voyage : au contact de ceux qui, chaque jour, perpétuent ce savoir-faire unique.

    L’accueil est chaleureux, franc, à l’image de ces femmes et ces hommes attachés à leur terre. On découvre les gestes précis de la traite, le soin apporté à chaque étape de la fabrication. Car ici, tout commence par le lait : un lait cru, riche, issu des pâturages denses de la Thiérache. Les vaches transforment l’herbe grasse de Thiérache en un lait exceptionnel. Un lait qui, une fois recueilli, entame sa métamorphose…

    Mains d’un fromager façonnant le caillé dans des moules pour donner au Maroilles AOP sa forme caractéristique, un savoir-faire traditionnel de Thiérache.
    Moulage artisanal du Maroilles AOP, une étape clé de sa fabrication.
    Gros plan sur les mains d’un artisan fromager taillant le caillé avant le moulage du Maroilles, dans le respect des méthodes traditionnelles.
    Taillage du caillé, une étape clé dans la fabrication du Maroilles AOP.
    Fromager brossant un Maroilles AOP dans une cave d’affinage, un geste essentiel pour développer sa croûte et ses arômes uniques.
    Brossage du Maroilles en cave, un soin minutieux pour un affinage optimal.
    Paysage de Thiérache avec des pommiers en fleurs, illustrant l’environnement naturel du Maroilles AOP.

    Épicurienne

    La Thiérache possède également une diversité de producteurs de pommes, de jus et de cidres. Un terroir riche en saveurs !

    De la ferme à l’assiette :
    l’instant gourmand

    Fromage Maroilles AOP sur une planche en bois, accompagné de pain rustique et d’une salade, pour une dégustation authentique du terroir de Thiérache.

    Un grand merci au Syndicat du Maroilles AOP, Louise et l’agence Rose & Piment pour cette mission !