PDF/R، المُعيَّاري كـ ISO 23504-1، هو ملف PDF للمستندات الممسوحة: تحمل كل صفحة صورة شريطية واحدة بالضبط ولا شيء غيرها. يتحقق منه مكوّن PDFium من Delphi وLazarus وC++Builder عبر ValidatePdfRCompliance، التي تقرأ دفقًا وتُعيد مستوى الامتثال زائد مجموعة من المشكلات الملموسة
الملف موجود لأن الماسحات وأنظمة التقاط المستندات احتاجت هدفًا أضيق من PDF/A. قد يحوي ملف PDF أرشيفي أي شيء يسمح به الجزء؛ ملف PDF نقطي مُفتَقر عمدًا، فيستطيع أي قارئ مطابق عرضه بشكل متطابق وأي كاتب مطابق إنتاجه من مسح بلا محرّك تأليف
ما الذي يحظره PDF/R ويسمح به PDF/A؟
النص عمليًا. تحمل الصفحة النقطية الصورة الممسوحة ولا شيء غيرها، فمورد خط على صفحة مخالفة — يُبلَّغ عنها كـ pvriFontForbidden تحت ISO 23504-1 §6.5.2. هذا يفاجئ من يضيف طبقة نص OCR غير مرئية للقابلية للبحث، وهو أمر طبيعي ومفيد في سير عمل PDF/A وببساطة ليس PDF/R
علاقة الصفحة بالصورة صارمة بالقدر نفسه. يجعل §6.5.1 كل صفحة صورة شريطية واحدة بالضبط، فيُطلَق pvriPageImageMismatch حين لا يطابق عدد الصور عدد الصفحات — صفحة بلا صورة وصفحة باثنتين كلاهما غير مطابقتين. ويُبلِّغ pvriBadMediaBox عن صفحة لا يحمل MediaBox الخاص بها الصيغة [0 0 w h] (§6.5.3)، لأن المسح ليس له سبب للجلوس عند أصل بإزاحة
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 — فاكس ثنائي، JPEG، JPEG 2000، وdeflate غير فادح، التي بينها تغطي كل إخراج ماسح يهم. كل ما عداه يُبلَّغ عنه كـ pvriForbiddenImageFilter، بما في ذلك /LZWDecode و/RunLengthDecode و/ASCII85Decode و/ASCIIHexDecode و/JBIG2Decode و/Crypt
اثنان من تلك الرفضين يستحقان الفهم لا الحفظ. /JBIG2Decode يضغط المسوحات الثنائية جيدًا جدًا وقانوني تمامًا في PDF/A، لكن إعادة بناء قاموس رموزها يستطيع استبدال رموز متشابهة بصريًا — نمط فشل موثَّق للأرقام الممسوحة — وملف غرضه كله التكاثر النقطي الأمين لا يقبل ذلك الخطر. تُستبعَد مرشّحات ASCII للسبب المعاكس: تنفخ الملف دون إضافة شيء يحتاجه ملف نقطي
قواعد بنية تُطلَق قبل قراءة أي صفحة
يقيّد PDF/R الحاوية أيضًا. يُبلِّغ pvriObjStmPresent عن دفق /Type /ObjStm، الذي يحظره الملف كليًة — تعقّد تدفقات الكائنات التحليل البسيط المتسلسل الذي يُفترَض بالقارئ النقطي أن يستطيع أداءه. يُبلِّغ pvriBadHeader عن ترويسة خارج %PDF-1.4 إلى 1.7 و%PDF-2.0، ويُبلِّغ pvriEncryptVersionMismatch عن ملف مشفَّر ترويسته ليست %PDF-2.0، وفق §6.2.3
الفهرس وقاموس Info على القائمة البيضاء، لا يُفحَصان فحسب. يُطلَق pvriProhibitedCatalogEntry وpvriProhibitedInfoEntry لمدخلات خارج المجموعة المسموح بها، ويُطلَق pvriInfoXmpMismatch حين يختلف مدخل Info عن مكافئه XMP. دفق /Metadata مفقود في الفهرس، و/ID مقطع مفقود، وعلامة تذييل %PDF-raster-1.0 الغائبة لكلٍّ منها مشكلتها الخاصة أيضًا
لماذا يحذف سجل خيارات الحفظ Title وAuthor
يحمل TPdfRSaveOptions Creator وProducer وCreationDate وModDate وDocumentId وInstanceId، وبتعمد بلا حقل لـ Title أو Author أو Subject أو Keywords. تلك الأربعة هي المدخلات التي يحظرها §6.4.3، فسجل يكشفها يدعو المستدعين لكتابة ملف غير مطابق عبر API مطابق
خياران منطقيان يتحكمان بالتنظيف عند تحويل PDF موجود. StripInfoOptionalEntries الافتراضي True ويزيل Title وAuthor وSubject وKeywords وTrapped من قاموس Info المصدر. StripCatalogOptionalEntries أيضًا افتراضي True ويزيل Names وOutlines وStructTreeRoot وOutputIntents وLang والباقي، تاركًا فقط القائمة البيضاء لـ §6.3. اضبط أيًّا منهما على False فتحتفظ بالمدخلات — وتخسر الامتثال، وهذا أحيانًا ما يريد المستدعي فعلًا لملف داخلي
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;
لاحظ ما لا يفعله حقن العلامات: يضيف بيانات وصفية وتحديدًا، ولا يستطيع تزويد محتوى الصفحة. صفحة مصدر لا تحمل صورة شريطية ستفشل في pvriPageImageMismatch بعد الحقن، لأن الصورة المفقودة لم تكن مشكلة بيانات وصفية أبدًا
أين يتناسب PDF/R في خط أنابيب التقاط
استخدمه حين يكون المُسلَّم هو المسح نفسه والأمانة العقد كله — تصوير بيّن، والتقاط الشيكات والإيصالات، وأرشيفات رسومات الهندسة من ماسح كبير الحجم. استخدم PDF/A بدلًا منه لحظة يحتاج المستند نصًا قابلًا للبحث، أو وسمًا، أو مرفقات مضمَّنة، أو أي شيء آخر يجرّده الملف النقطي
ترتيب شائع وعملي هو إنتاج كليهما: أصل PDF/R لا يتغير أبدًا، ومشتق PDF/A بطبقة OCR للاسترجاع. المُحقِّقان مستقلان، فيستطيع نفس العمل الدفعي فحص كل عنصر مقابل الملف الذي يطالب به فعلًا. للجانب الأرشيفي من ذلك الزوج، انظر ملاحظات امتثال PDF/A الأرشيفي وفحص PDF/A المسبق، وللإخراج الموجّه للطباعة شرح التحقق من مستندات PDF/X الجاهزة للطباعة
يجلب مكوّن PDFium محرّك PDFium إلى Delphi وC++Builder وLazarus بواجهة VCL ومُحقِّقات امتثال لـ PDF/A وPDF/X وPDF/E وPDF/UA وPDF/R — صفحة منتج مكوّن PDFium تسرد المعايير وإصدارات IDE المدعومة