PDF/R، استانداردشده بهعنوان ISO 23504-1، profile برای PDF اسناد اسکنشده است: هر صفحه دقیقاً یک تصویر نوار حمل میکند و هیچچیز دیگر. جزء PDFium آن را از Delphi، Lazarus و C++Builder از طریق ValidatePdfRCompliance اعتبارسنجی میکند، که یک stream میخواند و سطح انطباق بهاضافه مجموعهای از مسائل ملموس را برمیگرداند
profile وجود دارد چون پویشگرها و سیستمهای ضبط سند به هدفی باریکتر از PDF/A نیاز داشتند. یک PDF آرشیوی ممکن است هر چیزی که بخش اجازه میدهد در خود داشته باشد؛ یک PDF raster عمداً فقیر است، تا هر خواننده سازگار آن را یکسان نمایش دهد و هر نویسنده سازگار آن را از یک اسکن بدون یک موتور تألیف تولید کند
PDF/R چه چیزی را ممنوع میکند که PDF/A اجازه میدهد؟
در عمل، متن. یک صفحه raster تصویر اسکنشده را حمل میکند و هیچچیز دیگر، پس یک منبع فونت روی یک صفحه نقض است — بهعنوان pvriFontForbidden تحت ISO 23504-1 §6.5.2 گزارش میشود. این افرادی را که یک لایه متن OCR نامرئی برای قابلیت جستجو اضافه میکنند غافلگیر میکند، که یک کار معمول و مفید در یک workflow PDF/A است و ساده PDF/R نیست
رابطه صفحه به تصویر به همان شدت است. §6.5.1 هر صفحه را دقیقاً یک تصویر نوار میکند، پس pvriPageImageMismatch شلیک میکند وقتی شمار تصویر با شمار صفحه مطابقت ندارد — صفحهای با هیچ تصویر و صفحهای با دو تصویر هر دو ناسازگار هستند. و pvriBadMediaBox صفحهای را گزارش میدهد که MediaBox آن فرم [0 0 w h] ندارد (§6.5.3)، چون یک اسکن هیچ دلیلی برای نشستن در یک مبدأ offset ندارد
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;
کدام رمزگذاریهای تصویر مجاز هستند
چهار مورد، و لیست سفید به دلیلی کوتاه است. §6.6 /CCITTFaxDecode، /DCTDecode، /JPXDecode و /FlateDecode را میپذیرد — fax دوباینری، JPEG، JPEG 2000 و deflate بدون خطا، که میان خودشان هر خروجی پویشگری که اهمیت دارد را پوشش میدهند. هر چیز دیگر بهعنوان pvriForbiddenImageFilter گزارش میشود، شامل /LZWDecode، /RunLengthDecode، /ASCII85Decode، /ASCIIHexDecode، /JBIG2Decode و /Crypt
دو مورد از آن ردها ارزش فهمیدن دارند نه حفظکردن. /JBIG2Decode اسکنهای دوباینری را بهشدت فشرده میکند و در PDF/A کاملاً قانونی است، اما بازسازی دیکشنری نمادش میتواند گلیفهای بهنظرمشابه را جایگزین کند — یک حالت شکست مستند برای ارقام اسکنشده — و profileی که کل هدفش تولید raster صادقانه است نمیتواند آن خطر را بپذیرد. فیلترهای ASCII به دلیل مخالف مستثنی شدهاند: آنها فایل را بدون اضافهکردن چیزی که یک profile raster نیاز دارد باد میکنند
قواعد ساختار که قبل از خواندهشدن هر صفحهای شلیک میکنند
PDF/R container را نیز محدود میکند. pvriObjStmPresent یک stream /Type /ObjStm را گزارش میدهد، که profile آن را صریح ممنوع میکند — object streamها parse ساده و متوالی را که یک خواننده raster قرار است بتواند انجام دهد پیچیده میکنند. pvriBadHeader سرآینری خارج از %PDF-1.4 تا 1.7 و %PDF-2.0 را گزارش میدهد، و pvriEncryptVersionMismatch فایل رمزنگاریشدهای را که سرآیندش %PDF-2.0 نیست گزارش میدهد، طبق §6.2.3
کاتالوگ و دیکشنری Info لیست سفید هستند، نه صرفاً بررسیشده. pvriProhibitedCatalogEntry و pvriProhibitedInfoEntry برای entryهای خارج از مجموعه مجاز شلیک میکنند، و pvriInfoXmpMismatch شلیک میکند وقتی یک entry Info با معادل XMP خود مخالف است. یک stream /Metadata کاتالوگ مفقود، یک /ID trailer مفقود و یک نشانگر پاصفحه %PDF-raster-1.0 غایب هر کدام مسئله خودشان را دارند
چرا رکورد گزینههای ذخیره Title و Author را حذف میکند
TPdfRSaveOptions Creator، Producer، CreationDate، ModDate، DocumentId و InstanceId را حمل میکند، و عمداً هیچ فیلدی برای Title، Author، Subject یا Keywords ندارد. آن چهار entryهایی هستند §6.4.3 ممنوع میکند، پس رکوردی که آنها را افشا میکرد فراخوانندهها را به نوشتن فایل ناسازگار از طریق API سازگار دعوت میکرد
دو گزینه boolean پاکسازی هنگام تبدیل یک PDF موجود را کنترل میکنند. StripInfoOptionalEntries پیشفرض True و Title، Author، Subject، Keywords و Trapped را از دیکشنری Info منبع حذف میکند. StripCatalogOptionalEntries نیز پیشفرض True و Names، Outlines، StructTreeRoot، OutputIntents، Lang و بقیه را حذف میکند، و فقط لیست سفید §6.3 را باقی میگذارد. هر یک را روی False تنظیم کنید و entryها را نگه میدارید — و انطباق را از دست میدهید، که گاهی همان چیزی است یک فراخواننده واقعاً برای یک فایل داخلی میخواهد
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;
توجه کنید تزریق marker چه کار نمیکند: فراداده و شناسایی اضافه میکند، و نمیتواند محتوای صفحه فراهم کند. یک صفحه منبع که هیچ تصویر نوار حمل نمیکند هنوز پس از تزریق pvriPageImageMismatch شکست میخورد، چون تصویر مفقود هرگز یک مسئله فراداده نبود
PDF/R در یک pipeline ضبط کجا جای میگیرد
از آن جایی استفاده کنید که deliverable خود اسکن است و وفاداری کل قرارداد است — تصویربرداری شواهدی، ضبط چک و واریز، آرشیو نقشههای مهندتی از یک پویشگر فرمت بزرگ. بهجای آن از PDF/A لحظهای که سند به متن قابلجستجو، نشانهگذاری، پیوستهای جاسازیشده یا هر چیز دیگری که profile raster حذف میکند نیاز دارد استفاده کنید
ترتیبی رایج و کارآمد تولید هر دو است: یک PDF/R اصلی که هرگز تغییر نمیکند، و یک مشتق PDF/A با یک لایه OCR برای بازیابی. اعتبارسنجها مستقلاند، پس همان کار دستهای میتواند هر artifact را در برابر profileی که واقعاً ادعا میکند بررسی کند. برای جانب آرشیوی آن جفت، یادداشتهای انطباق آرشیوی PDF/A و اعتبارسنجی preflight برای PDF/A را ببینید، و برای خروجی چاپمحور مرور اعتبارسنجی اسناد آماده چاپ PDF/X
جزء PDFium موتور PDFium را به Delphi، C++Builder و Lazarus با یک API VCL و اعتبارسنجهای انطباق برای PDF/A، PDF/X، PDF/E، PDF/UA و PDF/R میآورد — صفحه محصول جزء PDFium استانداردهای پشتیبانیشده و نسخههای IDE را فهرست میکند