Il vecchio metodo era doloroso
Immagina un responsabile della conformità incaricato di verificare che ogni contratto in un’unità di rete contenga la parola “CONFIDENTIAL” e il logo aziendale su ogni pagina. Il processo attuale è così:
- Apri un file in un visualizzatore.
- Sfoglia ogni pagina alla ricerca della frase o dell’immagine.
- Annota le osservazioni in un foglio di calcolo.
- Ripeti l’operazione per migliaia di PDF, file Word e presentazioni.
Un singolo watermark mancante può innescare una costosa revisione, e lo sforzo manuale supera facilmente le 8 ore settimanali per un piccolo team. Inoltre, testo ruotato, parole spezzate o loghi salvati come immagini spesso sfuggono all’occhio umano, lasciando l’organizzazione esposta.
C’è un modo migliore
GroupDocs.Watermark for .NET elimina ogni passaggio di congettura. Il suo motore indipendente dal formato può leggere più di 100 tipi di documento, individuare watermark di testo, immagine e persino stilizzati, ed esporre tutti i metadati rilevanti tramite un’API pulita. Il tutorial seguente mostra come pochi snippet concisi sostituiscano il ciclo manuale con un flusso di lavoro automatizzato e ripetibile.
Prerequisiti
- .NET 6.0 o versioni successive.
- Pacchetto NuGet GroupDocs.Watermark (
dotnet add package GroupDocs.Watermark). - (Facoltativo) una licenza temporanea – vedi il collegamento alla fine di questo articolo.
Il nuovo modo: audit automatizzato dei watermark
Di seguito descriviamo quattro operazioni fondamentali. Ogni blocco è un esempio autonomo che puoi inserire in un’app console, in un passaggio CI o in un servizio in background.
Passo 1 – Scansiona tutti i watermark
Per prima cosa serve un inventario completo. Il metodo Search() restituisce una collezione in cui ogni voce contiene testo (o immagine), posizione, rotazione, numero di pagina e dimensione grezza dell’immagine.
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}");
}
}
Punto chiave: il ciclo termina in meno di un secondo per un PDF tipico di 50 pagine.
Passo 2 – Verifica il watermark di testo richiesto
Le politiche di conformità spesso richiedono una frase specifica (ad es., “CONFIDENTIAL”). TextSearchCriteria con SkipUnreadableCharacters gestisce automaticamente testo spezzato o ruotato.
using (var wk = new Watermarker(filePath))
{
var crit = new TextSearchCriteria(expectedPhrase);
crit.SkipUnreadableCharacters = true; // ignora artefatti OCR
var hits = wk.Search(crit);
bool ok = hits.Count > 0;
Console.WriteLine($" [{(ok ? "PASS" : "FAIL")}] " +
$"'{expectedPhrase}' found {hits.Count} time(s)");
return ok;
}
Il metodo restituisce true quando la frase appare almeno una volta, fornendo un immediato flag PASS/FAIL.
Passo 3 – Verifica il logo aziendale
I loghi sono immagini raster e il loro aspetto può variare leggermente a causa della compressione. ImageDctHashSearchCriteria crea un hash percettivo del logo di riferimento e lo confronta con una tolleranza configurabile.
using (var wk = new Watermarker(filePath))
{
var crit = new ImageDctHashSearchCriteria(logoPath);
crit.MaxDifference = 0.9; // tollera scaling/modifica colore moderata
var matches = wk.Search(crit);
bool ok = matches.Count > 0;
Console.WriteLine($" [{(ok ? "PASS" : "FAIL")}] " +
$"logo instances: {matches.Count}");
return ok;
}
Anche una copia a bassa risoluzione del logo verrà riconosciuta.
Passo 4 – Genera un report di conformità completo
Le politiche reali combinano diversi requisiti. Il blocco iniziale verifica quattro regole di formattazione — presenza del testo, font, dimensione e stile grassetto — ciascuna combinando TextSearchCriteria con TextFormattingSearchCriteria tramite .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 quinta regola verifica la copertura delle pagine — il watermark deve comparire su ogni pagina. Infine, il verdetto aggrega tutti i risultati:
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)");
}
Il report può essere esportato come JSON, CSV o inviato direttamente a un sistema di ticketing.
Confronto lato‑a‑lato: prima vs. dopo
| Revisione manuale | Audit automatizzato | |
|---|---|---|
| Tempo | Ore per lotto | Secondi per file |
| Precisione | Soggetta a errori umani | API deterministica |
| Scalabilità | Limitata a pochi documenti | Gestisce migliaia |
| Codice richiesto | Nessuno (ma lavoro intensivo) | ~30 righe di C# |
| Output | Solo ispezione visiva | Report strutturato PASS/FAIL |
Il contrasto è evidente: ciò che occupava un’intera giornata lavorativa ora gira come processo in background.
Esempio reale: libreria di contratti legali
Uno studio legale conserva 15 000 contratti in una cartella condivisa. La loro politica richiede la frase “CONFIDENTIAL – CLIENT XYZ” e il sigillo dello studio su ogni pagina. Integrando gli snippet sopra in uno script PowerShell notturno, lo studio ha ottenuto:
- 100 % di rilevamento dei marchi mancanti (in precedenza l'8 % sfuggiva).
- Zero ore manuali spese per l’audit.
- Una traccia di audit salvata in una lista interna di SharePoint per future revisioni normative.
// 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);
}
Lo script gira senza interventi e invia un riepilogo via email ogni mattina.
Cos’altro puoi fare con GroupDocs.Watermark?
Oltre all’audit, il progetto di esempio mostra come sostituire e rimuovere i watermark programmaticamente. Gli screenshot seguenti illustrano entrambe le operazioni su un PDF reale:
Altri scenari che puoi realizzare con la stessa API:
- Aggiungere watermark di tracciamento invisibili che incorporano un ID unico per il rintracciamento di eventuali perdite.
- Sostituire in blocco loghi obsoleti in tutto l’archivio.
- Generare certificati di conformità pronti per PDF dopo un audit riuscito.
- Integrare con Azure Functions o AWS Lambda per elaborazioni serverless.
Ogni scenario utilizza la stessa API di base – basta cambiare i criteri di ricerca o il tipo di watermark.
Conclusione
Ciò che una volta richiedeva a un team di sfogliare pagine, prendere appunti e rischiare di perdere dei marchi, ora è possibile con pochi secondi di codice che producono un report auditabile PASS/FAIL. Con GroupDocs.Watermark for .NET ottieni:
- Visibilità completa di ogni watermark.
- Rilevamento affidabile di testo, testo stilizzato e loghi.
- Reporting automatico della conformità.
- Possibilità di aggiornare o rimuovere i watermark programmaticamente.
Provalo e trasforma il tuo processo di conformità dei watermark da un mal di testa a un servizio ripetibile.
Prossimi passi
- Prova la versione di prova gratuita dell’API – ottieni una licenza temporanea qui: Temp License
- Leggi la documentazione completa per le opzioni avanzate: Docs
- Esplora il riferimento API .NET per tutte le classi e i metodi: API Reference
- Clona il progetto di esempio su GitHub per vedere un’app console completa: GitHub Samples
- Fai domande o condividi il tuo caso d’uso sul forum della community: Forum