Tehnični članak

Validacija optično braných dokumentov PDF/raster v Delphiju

PDF/R, standardiziran kot ISO 23504-1, je profil PDF za optično brane dokumente: vsaka stran nosi natanko eno pasovno sliko in nič drugega. PDFium Component ga validira iz Delphija, Lazarusa in C++Builderja skozi ValidatePdfRCompliance, ki prebere tok in vrne raven skladnosti plus množico konkretnih težav

Profil obstaja, ker so optični bralniki in sistemi zajema dokumentov potrebovali cilj ožji od PDF/A. Arhivski PDF lahko vsebuje kar koli, kar del dopušča; rasterski PDF je namerno osiromašen, tako lahko vsak skladni bralec prikaže enako in vsak skladni zapisovalnik ga lahko proizvede iz pregleda brez avtorskega pogona

Česar PDF/R prepoveduje, PDF/A pa dopušča?

V praksi besedilo. Rasterska stran nosi optično sliko in nič drugega, tako je vir pisave na strani kršitev — poročana kot pvriFontForbidden pod ISO 23504-1 §6.5.2. To preseneča ljudi, ki dodajo nevidno plast besedila OCR za iskanje, kar je v delovnem toku PDF/A normalna in uporabna stvar, pri PDF/R preprosto ni

Razmerje stran-slika je enako strogo. §6.5.1 naredi vsako stran natanko eno pasovno sliko, tako se pvriPageImageMismatch sproži, ko število slik ne ustreza številu strani — stran brez slike in stran z dvema sta obe neskladni. In pvriBadMediaBox poroča o strani, katere MediaBox nima oblike [0 0 w h] (§6.5.3), ker pregled nima razloga, da bi sedel pri odmaknjenem izvoru

uses FPdfPdfr;

var
  Src: TFileStream;
  Res: TPdfRValidationResult;
begin
  Src := TFileStream.Create('scan-batch-0142.pdf', fmOpenRead or fmShareDenyWrite);
  try
    Res := ValidatePdfRCompliance(Src);
    if Res.IsCompliant then
      Memo1.Lines.Add('PDF/R-1 conformant')
    else
    begin
      if pvriFontForbidden in Res.Issues then
        Memo1.Lines.Add('A page names a font resource; a raster page carries no text');
      if pvriPageImageMismatch in Res.Issues then
        Memo1.Lines.Add('Image count does not match page count');
      if pvriForbiddenImageFilter in Res.Issues then
        Memo1.Lines.Add('A strip image uses an encoding outside the white list');
    end;
  finally
    Src.Free;
  end;
end;

Katera kodiranja slik so dovoljena

Štiri in beli seznam je kratek iz razloga. §6.6 dopušča /CCITTFaxDecode, /DCTDecode, /JPXDecode in /FlateDecode — dvojni faks, JPEG, JPEG 2000 in brezizgubni deflate, ki med seboj pokrijejo vsak izhod optičnega bralnika, ki šteje. Vse drugo se poroča kot pvriForbiddenImageFilter, vključno z /LZWDecode, /RunLengthDecode, /ASCII85Decode, /ASCIIHexDecode, /JBIG2Decode in /Crypt

Dve od teh zavrnitev se splača razumeti in ne zapomniti. /JBIG2Decode izjemno dobro stisne dvojne preglede in je v PDF/A popolnoma zakonit, toda njegova rekonstrukcija slovarja simbolov lahko nadomesti vizualno podobne glasove — dokumentirani način odpovedi pri optično branih števkah — profil, katerega celoten namen je zvesta rasterska reprodukcija, pa ne more dopustiti tega tveganja. Filtri ASCII so izključeni iz nasprotnega razloga: datoteko napihnejo, ne da bi dodali karkoli, kar rasterski profil potrebuje

Strukturna pravila, ki se sprožijo, preden se prebere kakršna koli stran

PDF/R omejuje tudi vsebnik. pvriObjStmPresent poroča o toku /Type /ObjStm, ki ga profil prepoveduje naravnost — tokovi objektov zapletejo preprosto, zaporedno razčlenjevanje, ki naj bi ga rasterski bralec lahko izvedel. pvriBadHeader poroča o glavi zunaj %PDF-1.4 do 1.7 in %PDF-2.0, pvriEncryptVersionMismatch pa o šifrirani datoteki, katere glava ni %PDF-2.0, skladno s §6.2.3

Katalog in slovar Info sta na belem seznamu in ne le preverjena. pvriProhibitedCatalogEntry in pvriProhibitedInfoEntry se sprožita za vnose zunaj dovoljene množice, pvriInfoXmpMismatch pa se sproži, ko se vnos Info ne strinja s svojim ustreznikom XMP. Manjkajoč tok /Metadata kataloga, manjkajoči /ID prikolice in odsotna oznaka noge %PDF-raster-1.0 imajo vsaka svojo težavo

Zakaj zapis možnosti shranjevanja izpušča Title in Author

TPdfRSaveOptions nosi Creator, Producer, CreationDate, ModDate, DocumentId in InstanceId in namerno nima polja za Title, Author, Subject ali Keywords. Ta štiri so vnosi, ki jih §6.4.3 prepoveduje, zato bi zapis, ki bi jih izpostavil, vabil klicatelje, da skozi skladen API zapišejo neskladno datoteko

Dve boolean možnosti nadzirata čiščenje pri pretvarjanju obstoječega PDF. StripInfoOptionalEntries je privzeto True in iz izvornega slovarja Info odstrani Title, Author, Subject, Keywords in Trapped. StripCatalogOptionalEntries je prav tako privzeto True in odstrani Names, Outlines, StructTreeRoot, OutputIntents, Lang in ostalo, pri čemer pusti le beli seznam §6.3. Nastavite oboje na False in obdržite vnose — in izgubite skladnost, kar je občasno tisto, kar klicatelj resnično želi za notranjo datoteko

var
  Opts: TPdfRSaveOptions;
  Src, Dest: TFileStream;
begin
  Opts := TPdfRSaveOptions.Default;
  Opts.Creator := 'Capture Station 4';
  Opts.Producer := 'PDFium Component';
  Src := TFileStream.Create('scan-in.pdf', fmOpenRead or fmShareDenyWrite);
  try
    Dest := TFileStream.Create('scan-pdfr.pdf', fmCreate);
    try
      InjectPdfRMarkers(Src, Dest, Opts);   // markers + metadata, not page content
    finally
      Dest.Free;
    end;
  finally
    Src.Free;
  end;
end;

Upoštevajte, česar injiciranje oznak ne stori: doda metapodatke in identifikacijo, ne more pa dobaviti vsebine strani. Izvorna stran, ki ne nosi pasovne slike, bo po injiciranju še vedno odpovedala pri pvriPageImageMismatch, ker manjkajoča slika nikoli ni bila težava metapodatkov

Kam sodi PDF/R v cevovod zajema

Uporabite ga tam, kjer je rezultat sam pregled in je zvestota celotna pogodba — dokazno slikanje, zajem čekov in plačil, arhivi inženirskih načrtov iz velikoformatnega optičnega bralnika. Uporabite PDF/A namesto njega v trenutku, ko dokument potrebuje iskalno besedilo, označevanje, vdelane priponke ali karkoli drugega, kar rasterski profil odstrani

Pogosta in obvladljiva ureditev je proizvesti oboje: izvirnik PDF/R, ki se nikoli ne spremeni, in izpeljanek PDF/A s plastjo OCR za iskanje. Validatorja sta neodvisna, tako lahko ista paketna naloga preveri vsak artefakt proti profilu, ki ga dejansko zahteva. Za arhirsko stran tega para glejte zapiske o arhirski skladnosti PDF/A in validaciji predleta PDF/A, za tisku orientiran izhod pa sprehod skozi validacijo za tisk pripravljenih dokumentov PDF/X

PDFium Component prinaša pogon PDFium v Delphi, C++Builder in Lazarus z API VCL in validatorji skladnosti za PDF/A, PDF/X, PDF/E, PDF/UA in PDF/R — stran izdelka PDFium Component našteva podprte standarde in različice IDE