در جریانهای کاری چاپ سازمانی، بایگانی و انطباق اسناد، یک فایل PDF نمیتواند به سادگی فقط "رندر" شود؛ بلکه باید مورد حسابرسی قرار گیرد. یک فایل PDF ممکن است حاوی گروههای شفافیت تخت نشده باشد که پردازندههای تصویر شطرنجی (RIP) قدیمی را از کار میاندازند، جاوا اسکریپت تعبیهشدهای داشته باشد که یک خطر امنیتی به همراه دارد، یا دارای تصاویر با وضوح پایینی باشد که هنگام چاپ در 300 DPI بسیار بیکیفیت به نظر میرسند.
این فرآیند بازرسی یک فایل PDF پیش از ورود به جریان کاری تولید با نام پیشبررسی (Preflighting) شناخته میشود. در این مقاله، بررسی خواهیم کرد که چگونه با بهرهگیری از قابلیتهای تجزیه سطح پایین در PDFium، یک ابزار حسابرسی ریسک و پیشبررسی خودکار در دلفی بسازیم.
بررسیهای کلیدی در مرحله پیشبررسی
یک حسابرسی ریسک استاندارد معمولاً موارد زیر را در یک فایل PDF بررسی میکند:
- عناصر تعاملی: اکشنهای جاوا اسکریپت، اکشنهای راهاندازی (اجرای برنامههای خارجی) و AcroForms.
- معیارهای منابع: وجود تصاویر با وضوح پایین یا فونتهای جاسازی شده مفقود.
- وضعیت امنیتی: رمزنگاری سند، نیاز به رمز عبور و مجوزهای دسترسی (مثلاً غیرفعال بودن امکان چاپ).
- استانداردهای سند: اعتبارسنجی نشانگرهای انطباق PDF/A یا PDF/X در متادیتای سند.
استخراج متادیتا و حاشیهنویسیهای PDF با PDFium
موتور PDFium یک C API قدرتمند را ارائه میدهد که در دلفی قابل استفاده است. برای انجام یک حسابرسی پیشبررسی، ما فقط صفحه را رندر نمیکنیم؛ بلکه در درخت اشیاء PDF حرکت میکنیم. بیایید نگاهی بیندازیم به نحوه پیمایش صفحات سند و بازرسی حاشیهنویسیها (annotations) برای یافتن اکشنهای جاوا اسکریپت بالقوه خطرناک.
uses
System.SysUtils, pdfium_lib;
procedure AuditPdfSecurity(const FileName: string);
var
Doc: FPDF_DOCUMENT;
PageCount, i, j: Integer;
Page: FPDF_PAGE;
AnnotCount: Integer;
Annot: FPDF_ANNOTATION;
AnnotSubType: FPDF_ANNOTATION_SUBTYPE;
Action: FPDF_ACTION;
ActionType: ULONG;
begin
FPDF_InitLibrary();
try
// Load the document without a password
Doc := FPDF_LoadDocument(PAnsiChar(AnsiString(FileName)), nil);
if Doc = nil then
raise Exception.Create('Failed to load document or password required.');
try
PageCount := FPDF_GetPageCount(Doc);
Writeln(Format('Auditing %d pages...', [PageCount]));
for i := 0 to PageCount - 1 do
begin
Page := FPDF_LoadPage(Doc, i);
if Page <> nil then
begin
AnnotCount := FPDFPage_GetAnnotCount(Page);
for j := 0 to AnnotCount - 1 do
begin
Annot := FPDFPage_GetAnnot(Page, j);
if Annot <> nil then
begin
AnnotSubType := FPDFAnnot_GetSubtype(Annot);
// Check for Link Annotations that might have malicious actions
if AnnotSubType = FPDF_ANNOT_LINK then
begin
Action := FPDFAnnot_GetLinkAction(Annot);
if Action <> nil then
begin
ActionType := FPDFAction_GetType(Action);
// 2 represents PDFACTION_URI, 3 represents PDFACTION_SOUND, 4 represents PDFACTION_MOVIE
// We specifically look out for PDFACTION_LAUNCH or PDFACTION_JAVA_SCRIPT
if (ActionType = PDFACTION_JAVA_SCRIPT) or (ActionType = PDFACTION_LAUNCH) then
begin
Writeln(Format('WARNING: Malicious action detected on page %d', [i + 1]));
end;
end;
end;
FPDFPage_CloseAnnot(Annot);
end;
end;
FPDF_ClosePage(Page);
end;
end;
finally
FPDF_CloseDocument(Doc);
end;
finally
FPDF_DestroyLibrary();
end;
end;بررسی وضوح تصاویر
یکی دیگر از مراحل مهم پیشبررسی برای جریانهای کاری چاپ، اطمینان از این است که هیچ تصویری کمتر از آستانه DPI خاصی نباشد. PDFium به شما امکان میدهد اشیاء تصویری را مستقیماً از جریان صفحه استخراج کنید. با تقسیم ابعاد پیکسل تصویر استخراج شده بر ابعاد فیزیکی (بر حسب پوینت) که در صفحه PDF اشغال میکند، میتوانید DPI موثر را محاسبه کنید.
procedure AuditPageImages(Page: FPDF_PAGE);
var
ObjCount, i: Integer;
PageObj: FPDF_PAGEOBJECT;
ImgWidth, ImgHeight: Integer;
begin
ObjCount := FPDFPage_CountObjects(Page);
for i := 0 to ObjCount - 1 do
begin
PageObj := FPDFPage_GetObject(Page, i);
if FPDFPageObj_GetType(PageObj) = FPDF_PAGEOBJ_IMAGE then
begin
FPDFImageObj_GetBitmap(PageObj); // Returns an FPDF_BITMAP you can inspect
// Retrieve metadata using FPDFImageObj_GetImageMetadata
// Calculate effective DPI based on quad coordinates
end;
end;
end;یکپارچهسازی با PDFium Component
ساخت یک موتور پیشبررسی قدرتمند از پایه با استفاده از C API خام در PDFium نیازمند کدهای تکراری قابل توجه و دانش عمیق از مشخصات PDF است. استفاده از یک پوششدهنده (wrapper) این کار را بسیار ساده میکند. با یک پوششدهنده سطح بالا در دلفی، میتوانید تکرارهای پیچیده اشارهگرها در C را به یک کد شیءگرای تمیز تبدیل کنید.
با خودکارسازی مرحله پیشبررسی، شما از ورود فایلهای نامعتبر به خط لوله تولید خود جلوگیری کرده و در زمان و منابع رندرینگ صرفهجویی میکنید.
توجه: قابلیتهای پیشرفته تجزیه PDF و پیشبررسی به طور کامل در کامپوننت PDFium Component VCL پشتیبانی میشوند.