U tokovima posla vezanim za štampanje u preduzećima, arhiviranje i usklađenost dokumenata, PDF datoteka se ne može jednostavno "prikazati". Ona se mora revidirati. PDF može sadržati neporavnate (unflattened) grupe transparentnosti koje obaraju starije procesore rasterske slike (RIP), ugrađeni JavaScript koji predstavlja bezbednosni rizik, ili slike niske rezolucije koje će izgledati užasno kada se štampaju u 300 DPI.
Ovaj proces inspekcije PDF-a pre nego što uđe u produkcijski radni tok poznat je kao Preflight provera. U ovom članku ćemo istražiti kako da izgradite automatizovani alat za preflight proveru i reviziju rizika u Delphiju, koristeći mogućnosti parsiranja niskog nivoa koje nudi PDFium.
Ključne Preflight provere
Standardna revizija rizika obično proverava sledeće elemente unutar PDF-a:
- Interaktivni elementi: JavaScript akcije, Launch akcije (pokretanje eksternih programa) i AcroForms.
- Metrika resursa: Prisustvo slika niske rezolucije ili nedostajući ugrađeni fontovi.
- Bezbednosni status: Šifrovanje dokumenta, zahtevi za lozinkom i dozvole pristupa (npr. onemogućeno štampanje).
- Standardi dokumenata: Validacija PDF/A ili PDF/X markera usklađenosti u metapodacima dokumenta.
Izdvajanje PDF metapodataka i anotacija pomoću PDFiuma
PDFium obezbeđuje robustan C API koji Delphi može da koristi. Da bismo obavili preflight reviziju, mi ne prikazujemo samo stranicu; mi prolazimo kroz stablo PDF objekata. Pogledajmo kako proći kroz stranice dokumenta i pregledati anotacije kako bismo pronašli potencijalno rizične JavaScript akcije.
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;
Provera rezolucije slike
Još jedan kritičan korak preflight provere za tokove štampe je osiguravanje da nijedna slika ne padne ispod određenog DPI praga. PDFium vam omogućava da izdvojite objekte slika direktno iz toka stranice. Deljenjem dimenzija u pikselima izdvojene slike sa fizičkim dimenzijama (u tačkama) koje ona zauzima na PDF stranici, možete izračunati efektivni 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;
Integracija sa PDFium Component-om
Izgradnja robusnog preflight mehanizma od nule koristeći sirovi PDFium C API zahteva značajan šablonski kod (boilerplate) i duboko poznavanje PDF specifikacije. Korišćenje omotača (wrapper-a) ovo neizmerno pojednostavljuje. Sa Delphi omotačem visokog nivoa, složene iteracije C pokazivača možete pretvoriti u čist objektno-orijentisani kod.
Automatizacijom preflight faze, sprečavate loše datoteke da zaguše vaš produkcijski cevovod, štedeći i vreme i resurse za prikazivanje.
Napomena: Napredno parsiranje PDF-a i mogućnosti preflight provera su u potpunosti podržani od strane PDFium Component VCL komponente.