PDF/R, standardiserat som ISO 23504-1, är PDF-profilen för skannade dokument: varje sida bär exakt en remsbild och ingenting annat. PDFium Component validerar den från Delphi, Lazarus och C++Builder genom ValidatePdfRCompliance, som läser en ström och returnerar överensstämmelsenivån plus en mängd konkreta issues
Profilen existerar eftersom skannrar och dokumentfångstsystem behövde ett mål smalare än PDF/A. En arkiv-PDF får innehålla vad delen än tillåter; en raster-PDF är avsiktligt avmagrad, så att varje överensstämmande läsare kan visa den identiskt och varje överensstämmande skrivare kan producera den från en skanning utan en författarmotor
Vad förbjuder PDF/R som PDF/A tillåter?
Text, i praktiken. En raster-sida bär den skannade bilden och ingenting annat, så en teckensnittsresurs på en sida är en överträdelse — rapporterad som pvriFontForbidden under ISO 23504-1 §6.5.2. Det överraskar folk som lägger till ett osynligt OCR-textlager för sökbarhet, vilket är en normal och användbar sak att göra i ett PDF/A-arbetsflöde och enkelt inte är PDF/R
Relationen sida-till-bild är lika strikt. §6.5.1 gör varje sida till exakt en remsbild, så pvriPageImageMismatch avfyras när bildantalet inte matchar sidantalet — en sida utan bild och en sida med två är båda icke-överensstämmande. Och pvriBadMediaBox rapporterar en sida vars MediaBox inte har formen [0 0 w h] (§6.5.3), eftersom en skanning inte har någon anledning att sitta vid en förskjuten origin
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;
Vilka bildkodningar som är tillåtna
Fyra, och vitlistan är kort av en anledning. §6.6 medger /CCITTFaxDecode, /DCTDecode, /JPXDecode och /FlateDecode — två-nivå fax, JPEG, JPEG 2000 och förlustfri deflate, vilka mellan dem täcker varje skannerutdata som betyder något. Allt annat rapporteras som pvriForbiddenImageFilter, inklusive /LZWDecode, /RunLengthDecode, /ASCII85Decode, /ASCIIHexDecode, /JBIG2Decode och /Crypt
Två av dessa förkastanden är värda att förstå i stället för att memorera. /JBIG2Decode komprimerar två-nivå-skanningar extremt bra och är fullt lagligt i PDF/A, men dess symboldictionary-rekonstruktion kan byta ut visuellt lika glyfer — ett dokumenterat feltillstånd för skannade siffror — och en profil vars hela syfte är trogen rasterreproduktion kan inte medge den risken. ASCII-filterna exkluderas av motsatt anledning: de blåser upp filen utan att lägga till någonting en rasterprofil behöver
Strukturregler som avfyras innan någon sida läses
PDF/R begränsar även containern. pvriObjStmPresent rapporterar en /Type /ObjStm-ström, vilken profilen förbjuder rakt av — objektströmmar komplicerar den enkla, sekventiella tolkning som en rasterläsare är avsedd att kunna utföra. pvriBadHeader rapporterar en header utanför %PDF-1.4 till 1.7 och %PDF-2.0, och pvriEncryptVersionMismatch rapporterar en krypterad fil vars header inte är %PDF-2.0, enligt §6.2.3
Katalogen och Info-ordboken är vitlistade, inte bara kontrollerade. pvriProhibitedCatalogEntry och pvriProhibitedInfoEntry avfyras för poster utanför den tillåtna mängden, och pvriInfoXmpMismatch avfyras när en Info-post inte stämmer med sin XMP-motsvarighet. En saknad katalog /Metadata-ström, en saknad trailer /ID och en frånvarande %PDF-raster-1.0-sidfotmarkör har var och en sitt eget issue likaså
Varför sparalternativsposten utelämnar Title och Author
TPdfRSaveOptions bär Creator, Producer, CreationDate, ModDate, DocumentId och InstanceId, och har avsiktligt inget fält för Title, Author, Subject eller Keywords. De fyra är de poster §6.4.3 förbjuder, så en post som exponerade dem skulle bjuda in anropare att skriva en icke-överensstämmande fil genom ett överensstämmande API
Två booleska optioner styr upprensning vid konvertering av en befintlig PDF. StripInfoOptionalEntries är som standard True och tar bort Title, Author, Subject, Keywords och Trapped från källans Info-ordbok. StripCatalogOptionalEntries är också som standard True och tar bort Names, Outlines, StructTreeRoot, OutputIntents, Lang och resten, vilket lämnar endast §6.3-vitlistan. Sätt endera till False så behåller du posterna — och förlorar överensstämmelse, vilket ibland är vad en anropare genuint vill för en intern fil
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;
Notera vad märkinjektion inte gör: den lägger till metadata och identifiering, och kan inte tillhandahålla sidinnehåll. En källsida som bär ingen remsbild kommer fortfarande misslyckas pvriPageImageMismatch efter injektion, eftersom den saknade bilden aldrig var ett metadataproblem
Var PDF/R passar i ett fångstflöde
Använd det där leveransen är själva skanningen och fidelity är hela kontraktet — bevisbilddokumentation, check- och betalningsfångst, ingenjörsritningsarkiv från en storformatsskanner. Använd PDF/A i stället i det ögonblick dokumentet behöver sökbar text, taggning, inbäddade bilagor eller något annat rasterprofilen tar bort
Ett vanligt och fungerande arrangemang är att producera båda: ett PDF/R-original som aldrig ändras, och en PDF/A-derivat med ett OCR-lager för hämtning. Validatorerna är oberoende, så samma batchjobb kan kontrollera varje artefakt mot den profil den faktiskt gör anspråk på. För arkivsidan av det paret, se noterna om PDF/A-arkivefterlevnad och PDF/A-preflight-validering, och för tryckorienterad utdata genomgången av att validera tryckfärdiga PDF/X-dokument
PDFium Component för PDFium-motorn till Delphi, C++Builder och Lazarus med ett VCL-API och överensstämmelsevaliderare för PDF/A, PDF/X, PDF/E, PDF/UA och PDF/R — PDFium Component-produktsidan listar de standarder och IDE-versioner som stöds