วิธีเดิมทำให้เจ็บปวด
ลองนึกภาพเจ้าหน้าที่ปฏิบัติตามกฎระเบียบที่ต้องตรวจสอบว่าแต่ละสัญญาในไดรฟ์ที่ใช้ร่วมกันมีคำ “CONFIDENTIAL” และโลโก้ของบริษัทบนทุกหน้า กระบวนการปัจจุบันเป็นดังนี้
- เปิดไฟล์ในตัวดูไฟล์
- เลื่อนดูแต่ละหน้าเพื่อค้นหาคำหรือรูปภาพ
- จดบันทึกลงในสเปรดชีต
- ทำซ้ำสำหรับไฟล์ PDF, Word และงานนำเสนอหลายพันไฟล์
สัญลักษณ์ลายน้ำที่พลาดไปเพียงหนึ่งครั้งอาจทำให้ต้องตรวจทานใหม่ซึ่งมีค่าใช้จ่ายสูง และความพยายามแบบแมนนวลมักเกิน 8 ชั่วโมงต่อสัปดาห์ สำหรับทีมขนาดเล็ก นอกจากนี้ข้อความที่หมุน, คำที่แยกเป็นส่วน หรือโลโก้ที่บันทึกเป็นรูปภาพมักหลุดรอดจากสายตามนุษย์ ทำให้องค์กรเสี่ยงต่อการเปิดเผยข้อมูล
มีวิธีที่ดีกว่า
GroupDocs.Watermark for .NET ลบขั้นตอนที่ต้องคาดเดาออกไปทั้งหมด เครื่องยนต์ที่ไม่ขึ้นกับรูปแบบสามารถอ่านเอกสารได้มากกว่า 100 ประเภท ค้นหาข้อความ, รูปภาพและลายน้ำที่มีสไตล์ต่าง ๆ และเปิดเผยเมตาดาต้าที่เกี่ยวข้องทั้งหมดผ่าน API ที่เรียบง่าย บทแนะนำต่อไปนี้จะแสดงว่าชุดโค้ดสั้น ๆ สามบรรทัดสามารถแทนที่การทำงานแบบแมนนวลด้วยเวิร์กโฟลว์อัตโนมัติที่ทำซ้ำได้อย่างไร
ข้อกำหนดเบื้องต้น
- .NET 6.0 หรือใหม่กว่า
- แพ็กเกจ NuGet GroupDocs.Watermark (
dotnet add package GroupDocs.Watermark) - (ไม่บังคับ) ใบอนุญาตชั่วคราว – ดูลิงก์ที่ส่วนท้ายของบทความนี้
วิธีใหม่: การตรวจสอบลายน้ำอัตโนมัติ
ด้านล่างเราจะเดินผ่านสี่การดำเนินการหลัก แต่ละบล็อกเป็นตัวอย่างที่ทำงานได้เองซึ่งคุณสามารถใส่ลงในแอปคอนโซล, ขั้นตอน CI หรือบริการพื้นหลังได้
ขั้นตอน 1 – สแกนลายน้ำทั้งหมด
ก่อนอื่นเราต้องทำรายการเต็ม Search() จะคืนคอลเลกชันที่แต่ละรายการมีข้อความ (หรือรูปภาพ), ตำแหน่ง, การหมุน, หมายเลขหน้าและขนาดภาพดิบ
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}");
}
}
จุดสำคัญ: ลูปนี้ทำงานภายในไม่ถึงหนึ่งวินาทีสำหรับ PDF 50‑หน้าทั่วไป
ขั้นตอน 2 – ตรวจสอบลายน้ำข้อความที่ต้องการ
นโยบายการปฏิบัติตามมักกำหนดวลีเฉพาะ (เช่น “CONFIDENTIAL”) TextSearchCriteria พร้อม SkipUnreadableCharacters จะจัดการกับข้อความที่แยกหรือหมุนโดยอัตโนมัติ
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;
}
เมธอดจะคืนค่า true เมื่อวลีปรากฏอย่างน้อยหนึ่งครั้ง ให้คุณได้สัญญาณ PASS/FAIL ทันที
ขั้นตอน 3 – ตรวจสอบโลโก้บริษัท
โลโก้เป็นภาพแรสเตอร์และอาจมีการเปลี่ยนแปลงเล็กน้อยจากการบีบอัด ImageDctHashSearchCriteria สร้างแฮชเชิงรับรู้ของโลโก้อ้างอิงและเปรียบเทียบด้วยค่าความคลาดเคลื่อนที่กำหนดได้
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;
}
แม้จะเป็นสำเนาคุณภาพต่ำของโลโก้ก็จะถูกตรวจจับได้
ขั้นตอน 4 – รันรายงานการปฏิบัติตามแบบเต็มรูปแบบ
นโยบายในโลกจริงมักรวมหลายข้อกำหนด บล็อกแรกตรวจสอบสี่กฎการจัดรูปแบบ — การมีข้อความ, ฟอนต์, ขนาดและสไตล์หนา — โดยผสาน TextSearchCriteria กับ TextFormattingSearchCriteria ผ่าน .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++;
กฎที่ห้าตรวจสอบการครอบคลุมหน้า — ลายน้ำต้องปรากฏบนทุกหน้า สุดท้ายผลสรุปจะรวมผลทั้งหมดเข้าด้วยกัน
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)");
}
รายงานพร้อมส่งออกเป็น JSON, CSV หรือส่งต่อโดยตรงไปยังระบบตั๋ว
การเปรียบเทียบแบบเคียงข้าง: ก่อน vs. หลัง
| การตรวจสอบแบบแมนนวล | การตรวจสอบอัตโนมัติ | |
|---|---|---|
| เวลา | ชั่วโมงต่อชุด | วินาทีต่อไฟล์ |
| ความแม่นยำ | มีความผิดพลาดของมนุษย์ | API เชิงกำหนด |
| ความสามารถขยาย | จำกัดจำนวนเอกสาร | รองรับหลายพันไฟล์ |
| โค้ดที่ต้องใช้ | ไม่มี (แต่ใช้แรงงานมาก) | ประมาณ 30 บรรทัด C# |
| ผลลัพธ์ | ตรวจสอบด้วยสายตาเท่านั้น | รายงาน PASS/FAIL แบบโครงสร้าง |
ความแตกต่างชัดเจน: สิ่งที่เคยใช้เวลาทั้งวันทำงานเต็มวัน ตอนนี้ทำเป็นงานเบื้องหลังได้ในพริบตา
ตัวอย่างจากโลกจริง: ห้องสมุดสัญญากฎหมาย
บริษัทกฎหมายเก็บ 15 000 สัญญาไว้ในโฟลเดอร์ที่ใช้ร่วมกัน นโยบายของพวกเขาต้องการวลี “CONFIDENTIAL – CLIENT XYZ” และตราประทับของบริษัทบนทุกหน้า โดยการรวมสคริปต์ข้างต้นเข้าไปในสคริปต์ PowerShell ที่ทำงานทุกคืน บริษัทบรรลุผลดังนี้
- การตรวจจับ 100 % ของลายน้ำที่หายไป (ก่อนหน้านี้หลุดผ่าน 8 %)
- ศูนย์ชั่วโมงทำงานแมนนวล สำหรับการตรวจสอบ
- บันทึกการตรวจสอบ ถูกบันทึกลงในรายการ SharePoint ภายในเพื่อการตรวจสอบตามกฎระเบียบในอนาคต
// 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);
}
สคริปต์ทำงานโดยไม่ต้องดูแลและส่งอีเมลสรุปทุกเช้า
คุณสามารถทำอะไรได้อีกกับ GroupDocs.Watermark?
นอกเหนือจากการตรวจสอบ ตัวอย่างโปรเจกต์ยังแสดงวิธี replace และ remove ลายน้ำโดยโปรแกรม ภาพหน้าจอด้านล่างแสดงการทำงานทั้งสองบน PDF จริง
สถานการณ์อื่น ๆ ที่คุณสามารถสร้างด้วย API เดียวกัน
- เพิ่มลายน้ำติดตามที่มองไม่เห็น ที่ฝังรหัส ID เฉพาะสำหรับการติดตามการรั่วไหล
- แทนที่โลโก้ล้าสมัยเป็นจำนวนมาก ทั่วคลังข้อมูลทั้งหมด
- สร้างใบรับรองการปฏิบัติตามที่พร้อม PDF หลังจากการตรวจสอบสำเร็จ
- ผสานกับ Azure Functions หรือ AWS Lambda เพื่อประมวลผลแบบ serverless
แต่ละสถานการณ์ใช้ API แกนเดียวกัน – เพียงสลับเกณฑ์การค้นหาหรือประเภทลายน้ำ
สรุป
สิ่งที่เคยต้องใช้ทีมคนพลิกหน้า, จดบันทึกและเสี่ยงต่อการพลาดลายน้ำ ตอนนี้เป็น ไม่กี่วินาทีของโค้ด ที่สร้างรายงาน PASS/FAIL ที่ตรวจสอบได้ ด้วย GroupDocs.Watermark for .NET คุณจะได้:
- การมองเห็นเต็มรูปแบบของลายน้ำทุกตัว
- การตรวจจับข้อความ, ข้อความที่มีสไตล์และโลโก้อย่างเชื่อถือได้
- รายงานการปฏิบัติตามอัตโนมัติ
- ความสามารถในการอัปเดตหรือเอาลายน้ำออกโดยโปรแกรม
ลองใช้และเปลี่ยนกระบวนการตรวจสอบลายน้ำจากอาการปวดหัวให้เป็นบริการที่ทำซ้ำได้
ขั้นตอนต่อไป
- ลองใช้การทดลอง API ฟรี – รับใบอนุญาตชั่วคราวได้ที่นี่: Temp License
- อ่านเอกสารเต็ม สำหรับตัวเลือกขั้นสูง: Docs
- สำรวจอ้างอิง API .NET สำหรับคลาสและเมธอดทั้งหมด: API Reference
- โคลนโปรเจกต์ตัวอย่าง บน GitHub เพื่อดูแอปคอนโซลเต็มรูปแบบ: GitHub Samples
- ตั้งคำถาม หรือแบ่งปันกรณีการใช้งานของคุณในฟอรั่มชุมชน: Forum