У корпоративних робочих процесах друку, архівування та дотримання вимог до документів PDF-файл не можна просто "відрендерити". Його необхідно перевірити. PDF-файл може містити незведені групи прозорості, які призводять до збою застарілих растрових процесорів (RIP), вбудований JavaScript, що становить загрозу безпеці, або зображення з низькою роздільною здатністю, які виглядатимуть жахливо під час друку при 300 DPI.
Цей процес перевірки PDF-файлу перед його надходженням у виробничий робочий процес відомий як переддрукарська перевірка (Preflighting). У цій статті ми розглянемо, як створити автоматизований інструмент переддрукарської перевірки та аудиту ризиків у Delphi, використовуючи низькорівневі можливості синтаксичного аналізу PDFium.
Ключові переддрукарські перевірки
Стандартний аудит ризиків зазвичай перевіряє такі елементи в PDF-файлі:
- Інтерактивні елементи: Дії JavaScript, дії запуску (виконання зовнішніх програм) та AcroForms.
- Метрики ресурсів: Наявність зображень із низькою роздільною здатністю або відсутність вбудованих шрифтів.
- Статус безпеки: Шифрування документа, вимоги до пароля та дозволи доступу (наприклад, друк вимкнено).
- Стандарти документів: Перевірка маркерів відповідності PDF/A або PDF/X у метаданих документа.
Вилучення метаданих та анотацій PDF за допомогою PDFium
PDFium надає надійний C API, який можна використовувати в Delphi. Для виконання переддрукарського аудиту ми не просто рендеримо сторінку; ми обходимо дерево об'єктів PDF. Давайте подивимося, як ітерувати сторінки документа та перевіряти анотації, щоб знайти потенційно ризиковані дії JavaScript.
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. Використання обгортки значно спрощує це завдання. За допомогою високорівневої обгортки для Delphi ви можете перетворити складні ітерації вказівників C на чистий об'єктно-орієнтований код.
Автоматизувавши етап переддрукарської перевірки, ви запобігаєте потраплянню поганих файлів у ваш виробничий конвеєр, заощаджуючи час і ресурси на рендеринг.
Примітка: Розширені можливості синтаксичного аналізу та переддрукарської перевірки PDF повністю підтримуються компонентом PDFium Component.