V podjetniškem tisku, arhiviranju in potekih dela za skladnost dokumentov datoteke PDF ni mogoče preprosto "upodobiti". Potrebno jo je revidirati. Datoteka PDF lahko vsebuje nesploščene skupine prosojnosti, ki povzročijo sesutje starejših procesorjev rastrskih slik (RIP), vgrajen JavaScript, ki predstavlja varnostno tveganje, ali slike nizke ločljivosti, ki bodo pri tisku na 300 DPI videti obupno.
Ta postopek pregledovanja datoteke PDF, preden vstopi v produkcijski proces, je znan kot Preflighting (Predogled). V tem članku bomo raziskali, kako v Delphiju zgraditi avtomatizirano orodje za predogled in revizijo tveganj z izkoriščanjem zmožnosti razčlenjevanja na nizki ravni mehanizma PDFium.
Ključna preverjanja v predogledu
Standardna revizija tveganj običajno preverja naslednje elemente znotraj PDF dokumenta:
- Interaktivni elementi: Akcije JavaScript, akcije za zagon (izvajanje zunanjih programov) in obrazci AcroForms.
- Metrika virov: Prisotnost slik z nizko ločljivostjo ali manjkajočih vdelanih pisav.
- Varnostni status: Šifriranje dokumenta, zahteve za geslo in dovoljenja za dostop (npr. onemogočeno tiskanje).
- Standardi dokumentov: Preverjanje skladnosti z oznakami PDF/A ali PDF/X v metapodatkih dokumenta.
Luščenje metapodatkov in opomb PDF s PDFium
PDFium zagotavlja robusten C API, ki ga lahko uporablja Delphi. Za izvedbo revizije v predogledu strani ne upodobimo le vizualno, temveč se sprehodimo po drevesu PDF objektov. Poglejmo, kako iterirati skozi strani dokumenta in pregledati opombe, da bi našli potencialno tvegane akcije 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;
Preverjanje ločljivosti slike
Še en kritičen korak predogleda za delovne procese tiskanja je zagotavljanje, da nobena slika ne pade pod določen prag DPI. PDFium vam omogoča neposredno luščenje objektov slik iz toka strani. Z deljenjem dimenzij v pikslih izluščene slike z njenimi fizičnimi dimenzijami (v točkah), ki jih zaseda na PDF strani, lahko izračunate 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 s PDFium Component
Gradnja robustnega mehanizma za predogled iz nič z uporabo surovega API-ja PDFium C zahteva precej stereotipne kode (boilerplate) in globoko poznavanje specifikacije PDF. Uporaba ovoja (wrapper) to izjemno poenostavi. Z Delphi ovojem na visoki ravni lahko pretvorite kompleksne iteracije kazalcev C v čisto, objektno usmerjeno kodo.
Z avtomatizacijo faze predogleda preprečite, da bi slabe datoteke zamašile vaš produkcijski cevovod, ter prihranite čas in vire upodabljanja.
Opomba: Napredno razčlenjevanje PDF in zmožnosti predogleda so v celoti podprte v komponenti PDFium Component.