L’ancienne méthode était pénible

Imaginez un responsable conformité chargé de vérifier que chaque contrat sur un lecteur partagé comporte le mot “CONFIDENTIAL” et le logo de l’entreprise sur chaque page. Le processus actuel ressemble à ceci :

  1. Ouvrir un fichier dans un visualiseur.
  2. Feuilleter chaque page à la recherche de la phrase ou de l’image.
  3. Prendre des notes dans une feuille de calcul.
  4. Répéter pour des milliers de PDF, fichiers Word et présentations.

Un seul filigrane manqué peut déclencher une révision coûteuse, et l’effort manuel dépasse facilement 8 heures par semaine pour une petite équipe. De plus, le texte tourné, les mots séparés ou les logos enregistrés comme images échappent souvent à l’œil humain, laissant l’organisation exposée.

Il existe une meilleure façon

GroupDocs.Watermark for .NET élimine chaque étape d’estimation. Son moteur agnostique du format peut lire plus de 100 types de documents, localiser le texte, l’image et même les filigranes stylisés, et exposer toutes les métadonnées pertinentes via une API propre. Le tutoriel suivant montre comment quelques extraits concis remplacent la boucle manuelle par un flux de travail automatisé et répétable.

Prérequis

  • .NET 6.0 ou version ultérieure.
  • GroupDocs.Watermark package NuGet (dotnet add package GroupDocs.Watermark).
  • (Optionnel) une licence temporaire – voir le lien à la fin de cet article.

La nouvelle façon : audit automatisé des filigranes

Ci‑dessous, nous parcourons quatre opérations principales. Chaque bloc est un exemple autonome que vous pouvez intégrer dans une application console, une étape CI ou un service en arrière‑plan.

Étape 1 – Analyser chaque filigrane

Tout d’abord, nous avons besoin d’un inventaire complet. La méthode Search() renvoie une collection où chaque entrée contient le texte (ou l’image), la localisation, la rotation, le numéro de page et la taille brute de l’image.

using (var wk = new Watermarker(filePath))
{
    var all = wk.Search();
    Console.WriteLine($"Found {all.Count} watermark(s) in " +
        $"'{Path.GetFileName(filePath)}':");
    int i = 0;
    foreach (var wm in all)
    {
        Console.WriteLine($"  #{++i}: {(wm.Text ?? "[image]")} ");
        Console.WriteLine($"     Page {wm.PageNumber}, " +
            $"Pos X={wm.X}, Y={wm.Y}, Rot={wm.RotateAngle}°");
        Console.WriteLine($"     Size {wm.Width}×{wm.Height}");
        if (wm.ImageData != null)
            Console.WriteLine($"     Image bytes {wm.ImageData.Length}");
    }
}

Point clé : la boucle s’exécute en moins d’une seconde pour un PDF typique de 50 pages.

Étape 2 – Vérifier le filigrane texte requis

Les politiques de conformité exigent souvent une phrase spécifique (par ex., “CONFIDENTIAL”). Le TextSearchCriteria avec SkipUnreadableCharacters gère automatiquement le texte séparé ou tourné.

using (var wk = new Watermarker(filePath))
{
    var crit = new TextSearchCriteria(expectedPhrase);
    crit.SkipUnreadableCharacters = true;   // ignore OCR artefacts
    var hits = wk.Search(crit);
    bool ok = hits.Count > 0;
    Console.WriteLine($"  [{(ok ? "PASS" : "FAIL")}] " +
        $"'{expectedPhrase}' found {hits.Count} time(s)");
    return ok;
}

La méthode renvoie true lorsque la phrase apparaît au moins une fois, vous donnant un indicateur PASS/FAIL instantané.

Étape 3 – Vérifier le logo de l’entreprise

Les logos survivent sous forme d’images raster, et leur apparence peut varier légèrement à cause de la compression. ImageDctHashSearchCriteria crée un hachage perceptuel du logo de référence et le compare avec une tolérance configurable.

using (var wk = new Watermarker(filePath))
{
    var crit = new ImageDctHashSearchCriteria(logoPath);
    crit.MaxDifference = 0.9;   // tolerate moderate scaling / colour shift
    var matches = wk.Search(crit);
    bool ok = matches.Count > 0;
    Console.WriteLine($"  [{(ok ? "PASS" : "FAIL")}] " +
        $"logo instances: {matches.Count}");
    return ok;
}

Même une copie à basse résolution du logo sera reconnue.

Étape 4 – Exécuter un rapport complet de conformité

Les politiques du monde réel combinent plusieurs exigences. Le premier bloc vérifie quatre règles de formatage — présence du texte, police, taille et style gras — chacune combinant TextSearchCriteria avec TextFormattingSearchCriteria via .And() :

using (var wk = new Watermarker(filePath))
{
    int passed = 0, failed = 0;

    var txtCrit = new TextSearchCriteria(expectedPhrase);
    bool hasText = wk.Search(txtCrit).Count > 0;
    Console.WriteLine($"  [{(hasText ? "PASS" : "FAIL")}] Text present");
    if (hasText) passed++; else failed++;

    var fontCrit = new TextFormattingSearchCriteria { FontName = expFont };
    bool hasFont = wk.Search(txtCrit.And(fontCrit)).Count > 0;
    Console.WriteLine($"  [{(hasFont ? "PASS" : "FAIL")}] Font {expFont}");
    if (hasFont) passed++; else failed++;

    var sizeCrit = new TextFormattingSearchCriteria { MinFontSize = minSize };
    bool hasSize = wk.Search(txtCrit.And(sizeCrit)).Count > 0;
    Console.WriteLine($"  [{(hasSize ? "PASS" : "FAIL")}] Size >= {minSize}");
    if (hasSize) passed++; else failed++;

    var boldCrit = new TextFormattingSearchCriteria { FontBold = true };
    bool hasBold = wk.Search(txtCrit.And(boldCrit)).Count > 0;
    Console.WriteLine($"  [{(hasBold ? "PASS" : "FAIL")}] Bold formatting");
    if (hasBold) passed++; else failed++;

La cinquième règle vérifie la couverture des pages — le filigrane doit apparaître sur chaque page. Enfin, le verdict agrège tous les résultats :

    var perPage = wk.Search(txtCrit);
    var pages = new HashSet<int>();
    foreach (var wm in perPage)
        if (wm.PageNumber.HasValue) pages.Add(wm.PageNumber.Value);
    var allPages = wk.Search();
    int max = 0;
    foreach (var wm in allPages)
        max = Math.Max(max, wm.PageNumber ?? 0);
    bool full = max > 0 && pages.Count == max;
    Console.WriteLine($"  [{(full ? "PASS" : "FAIL")}] " +
        $"Pages covered {pages.Count}/{max}");
    if (full) passed++; else failed++;

    string verdict = failed == 0 ? "COMPLIANT" : "NON-COMPLIANT";
    Console.WriteLine($"\nResult: {verdict} " +
        $"({passed} passed, {failed} failed)");
}

Le rapport est prêt à être exporté en JSON, CSV ou injecté directement dans un système de tickets.


Côte à côte : avant vs. après

Revue manuelle Audit automatisé
Temps Heures par lot Secondes par fichier
Précision Sujet aux erreurs humaines API déterministe
Scalabilité Limité à quelques documents Gère des milliers
Code requis Aucun (mais intensif en main‑d’œuvre) ~30 lignes de C#
Sortie Inspection visuelle uniquement Rapport structuré PASS/FAIL

Le contraste est frappant : ce qui occupait auparavant une journée entière s’exécute maintenant comme une tâche en arrière‑plan.


Exemple réel : bibliothèque de contrats juridiques

Un cabinet d’avocats stocke 15 000 contrats dans un dossier partagé. Leur politique exige la phrase “CONFIDENTIAL – CLIENT XYZ” et le sceau du cabinet sur chaque page. En intégrant les extraits ci‑dessus dans un script PowerShell nocturne, le cabinet a obtenu :

  • 100 % de détection des marques manquantes (auparavant 8 % passaient inaperçus).
  • Zéro heure manuelle consacrée à l’audit.
  • Une traçabilité d’audit enregistrée dans une liste SharePoint interne pour les futures revues réglementaires.
// Example of the nightly job entry point
var folder = @"\\fileserver\Contracts";
foreach (var pdf in Directory.GetFiles(folder, "*.pdf", SearchOption.AllDirectories))
{
    // reuse the methods from steps 1‑4
    ScanAll(pdf);
    VerifyText(pdf, "CONFIDENTIAL – CLIENT XYZ");
    VerifyLogo(pdf, @"C:\Logos\firm-seal.png");
    RunReport(pdf);
}

Le script s’exécute sans surveillance et envoie un résumé par courriel chaque matin.


Que pouvez‑vous faire d’autre avec GroupDocs.Watermark ?

Au‑delà de l’audit, le projet d’exemple montre comment remplacer et supprimer les filigranes programmatiquement. Les captures d’écran ci‑dessous illustrent les deux opérations sur un PDF réel :

Remplacement de texte — le vieux filigrane est mis à jour avec du nouveau texte, police et couleur

Suppression ciblée — seuls les filigranes correspondant à la fois au texte et aux critères de formatage sont supprimés

Autres scénarios que vous pouvez créer avec la même API :

  • Ajouter des filigranes de suivi invisibles qui intègrent un ID unique pour le traçage des fuites.
  • Remplacer en masse les logos obsolètes dans tout un archive.
  • Générer des certificats de conformité prêts pour PDF après un audit réussi.
  • Intégrer avec Azure Functions ou AWS Lambda pour le traitement sans serveur.

Chaque scénario utilise la même API de base – il suffit d’échanger les critères de recherche ou le type de filigrane.


Conclusion

Ce qui nécessitait autrefois qu’une équipe feuillette les pages, prenne des notes et risque de manquer des marques est désormais réalisé en quelques secondes de code qui produit un rapport PASS/FAIL auditable. Avec GroupDocs.Watermark for .NET vous obtenez :

  • Une visibilité totale sur chaque filigrane.
  • Une détection fiable du texte, du texte stylisé et des logos.
  • Un reporting de conformité automatisé.
  • La capacité de mettre à jour ou de supprimer les filigranes programmatiquement.

Essayez‑le et transformez votre processus de conformité des filigranes d’un casse‑tête en un service répétable.


Étapes suivantes

  • Try the free API trial – get a temporary license here: Temp License
  • Read the full documentation for advanced options: Docs
  • Explore the .NET API reference for all classes and methods: API Reference
  • Clone the sample project on GitHub to see a complete console app: GitHub Samples
  • Ask questions or share your use case on the community forum: Forum