مقال تقني

ضغط الصور ثنائية المستوى JBIG2 الأصلي في ملفات PDF في Delphi

يتكون العقد الممسوح ضوئياً من بضع مئات من النقاط لكل بوصة من الحبر الأسود على ورق أبيض. عند تخزينه كصورة نقطية بتنسيق بت واحد لكل بكسل، يكون حجمه صغيراً بالفعل، ومع ذلك، فإن مائة صفحة من هذا القبيل لا تزال تؤدي إلى تضخم ملف PDF بشكل يتجاوز أي شيء يمكنك إرساله عبر البريد الإلكتروني. المرشح المناسب يغير هذه الحسابات. يعد JBIG2 التشفير ذو النسبة الأعلى الذي يحدده معيار ISO 32000-1 للصور ثنائية المستوى، وفي حزمة من النصوص الممسوحة ضوئياً، فإنه عادةً ما يخفض ما ينتجه CCITT Group 4 إلى النصف. هذا هو المرشح الذي يجب اللجوء إليه عندما يكون الإدخال قادماً من فاكس أو ماسح ضوئي أو تم تقليله بطريقة أخرى إلى لونين، ويمكن لـ HotPDF كتابته مباشرة في ملف PDF

يحقق التنسيق هذه النسبة بفضل فكرتين لا يمتلكهما برنامج ترميز الصور العادي. فهو ينمذج كيفية استقرار المسارات السوداء مقابل خلفية بيضاء، ويلاحظ أن الصفحة الممسوحة ضوئياً تتكون غالباً من نفس المئات القليلة من أشكال الحروف الرسومية مكررة آلاف المرات. فهم كلتا الفكرتين هو ما يتيح لك اختيار خيارات التشفير بوعي بدلاً من التخمين

موقع JBIG2 في مواصفات PDF

يسرد معيار ISO 32000-1 JBIG2Decode من بين مرشحات التدفق في القسم 7.4.7، وهو متاح بدءاً من PDF 1.4. وينطبق على مكان واحد فقط: كائنات XObject للصور التي يكون /BitsPerComponent الخاص بها 1 ومساحة الألوان الخاصة بها تحل في قناة واحدة. وهذا هو بيت القصيد. JBIG2 هو برنامج ترميز ثنائي المستوى، لذلك لا يتنافس أبداً مع DCT أو JPXDecode في الصور الفوتوغرافية. بل يتنافس مع CCITTFaxDecode، مرشحات فاكس المجموعة 3 والمجموعة 4، وبالتحديد في نوع الصفحات ذات اللونين التي ينتجها الماسح الضوئي للمستندات

يستهلك جهاز فك التشفير تنظيم JBIG2 المضمن الذي يسميه المعيار بملف تعريف PDF، حيث يحتفظ كل تدفق صور بتسلسل من المقاطع بدلاً من تدفق بتات مجرد. يحمل التدفق الاختياري /JBIG2Globals المقاطع المشتركة عبر عدة صور في نفس المستند، وهي الآلية التي تسمح بتخزين المحتوى المكرر مرة واحدة لملف كامل بدلاً من مرة واحدة لكل صفحة. يقوم HotPDF بإصدار التدفق لكل صورة افتراضياً ويترك قناة المقاطع العامة فارغة ما لم يطلبها واجهة التشفير الخلفية

بنية المشفر القائمة على الواجهة الخلفية أولاً

يعد مشفر JBIG2 الكامل جزءاً ضخماً من البرامج، والأجزاء الأكثر قوة فيه كانت تاريخياً مقيدة ببراءات اختراع ويتم شحنها بموجب تراخيص لا تناسب كل منتج. يحل HotPDF هذا التوتر من خلال فصل الواجهة عن المحرك. تحدد وحدة HPDFJBIG2 الاستدعاءات التي تجريها بقية المكتبة، وتشحن مشفراً مدمجاً متواضعاً بحيث يعمل JBIG2 مباشرة بعد التثبيت. عندما تحتاج إلى نسب ضغط بمستوى الإنتاج، فإنك تقوم بتسجيل محرك أقوى وتقوم المكتبة بتفويض العمل إليه، دون أي تغيير في كود الاستدعاء الخاص بك

التبديل عبارة عن استدعاء تسجيل واحد. مع عدم تسجيل أي واجهة خلفية، يتراجع المشفر إلى مساره المدمج. سجل واحدة وسيتم تشغيل كل عملية تشفير لاحقة من خلالها

uses
  HPDFJBIG2;

// Query what is active, then optionally install a stronger engine.
if not IsJBIG2EncoderBackendAvailable then
  // Production backend not present: HotPDF uses its built-in MMR path.
  RegisterJBIG2EncoderBackend(MyVendorJBIG2Encode);

// Later, to return to the built-in behaviour:
// ClearJBIG2Backends;

يوجد نفس الإجراء لفك التشفير من خلال RegisterJBIG2DecoderBackend، مع IsJBIG2DecoderBackendAvailable لفحصه. هذا هو السبب في أن المكتبة تشحن مساراً مدمجاً صغيراً بالإضافة إلى نقطة اتصال للواجهة الخلفية بدلاً من مشفر واحد متآلف. يحافظ المسار المدمج على الثنائي رشيقاً وخالياً من تعقيدات الترخيص، بينما تتيح نقطة الاتصال للفريق الذي قام بترخيص مشفر كامل توصيله دون لمس طبقة كتابة PDF على الإطلاق

ما تبادله خيارات التشفير بالفعل

يتم تكوين التشفير من خلال TJBIG2EncodeOptions، وهو سجل يحتوي على الحقول Lossless و UseGlobalSegments و UseSymbolDictionary و LossyLevel. ينشر الغلاف الملائم للمكون THPDFJBIG2Options الحقول Lossless و UseSymbolDictionary و LossyLevel بحيث يمكن ضبطها من Object Inspector، ويقوم بالتحويل إلى السجل داخلياً. هناك ثلاثة أهداف تحرك الإعدادات

تستبقي عملية إعادة البناء غير المفقودة كل بكسل. اضبط Lossless على True واترك LossyLevel عند الصفر، وستكون الصورة النقطية التي تم فك تشفيرها مطابقة للبت للإدخال. هذا هو الخيار الآمن الوحيد للرسومات الخطية والرسومات الفنية وأي صفحة قد يؤدي فيها إسقاط بكسل إلى تغيير المعنى، مثل التوقيع أو الختم. يؤدي ترميز قاموس الرموز إلى تشغيل إلغاء البيانات المكررة المدرك للنص وهو الخيار الذي يفصل JBIG2 عن مرشحات الفاكس. يتيح مستوى الفقد، وهو عدد صحيح من 0 إلى 9، لواجهة خلفية قادرة مبادلة الدقة بالحجم من خلال التعامل مع العلامات شبه المتطابقة على أنها نفس الرمز. الصفر يعني عدم وجود فقد. يراعي المشفر المدمج فقط المسار غير المفقود ويتجاهل أي مستوى فقد غير صفري، وبالتالي لا تدخل المستويات الأعلى حيز التنفيذ إلا بمجرد تسجيل واجهة خلفية تنفذها

var
  Options: TJBIG2EncodeOptions;
begin
  Options := DefaultJBIG2EncodeOptions;   // Lossless True, symbol dictionary on
  Options.Lossless := True;
  Options.LossyLevel := 0;                // 0 keeps every pixel
  Options.UseSymbolDictionary := True;    // dedupe repeated glyphs
  // Pass Options to a backend, or let THPDFJBIG2Options carry them.
end;

قواميس الرموز ولماذا تفوز عمليات مسح النصوص

إن صفحة النص الممسوحة ضوئياً ليست حقاً صورة للكلمات. إنها نفس الحرف e مطبوعة عدة مئات من المرات، ونفس حرف t، ونفس الفاصلة، كل مثيل هو نسخة مشوشة قليلاً لشكل أساسي واحد. يلتقط قاموس الرموز هذه البنية. يجمع المشفر العلامات المميزة في الصفحة في قاموس، ويخزن كل شكل مرة واحدة، ثم يسجل الصفحة كقائمة من المواضع التي تشير إلى إدخالات القاموس. تكلف ألف تكرار لنفس الحرف الرسومي صورة نقطية مخزنة واحدة بالإضافة إلى ألف موضع رخيص

هذا هو بالضبط المكان الذي يتفوق فيه JBIG2 على CCITT Group 4. يقوم Group 4 بترميز كل خط مسح مقابل الخط الذي فوقه بدون مفهوم الحرف الرسومي، لذلك فهو يدفع التكلفة الكاملة لكل حرف في كل مرة يظهر فيها الحرف. يدفع JBIG2 مرة واحدة. عندما تتم ترقية نفس القاموس إلى تدفق المقاطع العامة على مستوى المستند، يتضاعف التوفير عبر عملية مسح ضوئي متعددة الصفحات، لأن الأشكال التي تشترك فيها صفحة تلو الأخرى يتم تخزينها مرة واحدة للملف بأكمله. بالنسبة للنصوص الكثيفة، لا يكون الفرق هامشياً. إنه السبب وراء وجود JBIG2

المنطقة العامة و MMR لكل شيء آخر

ليست كل صورة ثنائية المستوى نصاً. تحتوي الخرائط والمخططات والرسومات الهندسية والصفحات المختلطة على رسومات خطية لا يمكن لأي قاموس تلخيصها. بالنسبة لهذه الحالات، يقوم JBIG2 بترميز منطقة عامة، وهي مستطيل من البكسلات يتم ضغطها مباشرة دون أي تدريب على الرموز. يسمح المعيار للمنطقة العامة باستخدام MMR، وهو ترميز READ المعدل المعدل الذي تستخدمه بالفعل فاكس Group 4، والذي ينمذج كل صف من البكسلات مقابل الصف الذي فوقه

هذا هو المسار الذي يشحنه HotPDF في مشفره المدمج. عندما لا يتم تسجيل أي واجهة خلفية ويكون الطلب غير مفقود، تضغط المكتبة الصورة النقطية كمنطقة عامة MMR واحدة وتلفها في بنية مقطع JBIG2 التي يتطلبها ملف تعريف PDF. ولا يحتاج إلى قاموس ولا إلى مسار تدريب ولا إلى صورة ثانية للإشارة إليها، لذا فهو الإعداد الافتراضي الموثوق به للرسومات الخطية والمحتوى المختلط ثنائي المستوى. لن يضاهي مشفر قاموس الرموز الكامل للنصوص الخالصة، ولكنه دائماً صحيح ودائماً غير مفقود وموجود دائماً. سطح المشفر الخاص به هو استدعاء واحد

var
  Encoder: THPDFJBIG2Encoder;
  ImageData: TJBIG2ByteArray;
  Scanlines: TJBIG2ScanlineArray;  // one byte array per row, MSB-first
  W, H: Integer;
begin
  // Scanlines, W and H describe a 1-bit page; each row is (W + 7) div 8 bytes.
  Encoder := THPDFJBIG2Encoder.Create;
  try
    if Encoder.EncodeToByteArray(Scanlines, W, H, ImageData) then
      // ImageData now holds a JBIG2 stream ready for a /JBIG2Decode XObject.
      ;
  finally
    Encoder.Free;
  end;
end;

تشغيله عند إنشاء مستند

للاستخدام اليومي، لا تلمس فئة المشفر مباشرة. يعرض HotPDF JBIG2 كخيار ضغط للصور في المستند. يتضمن التعداد THPDFImageCompressionType الخيار icJBIG2 جنباً إلى جنب مع خيارات Flate و JPEG و CCITT، ويحمل المستند خاصية JBIG2Options من النوع THPDFJBIG2Options التي تحتفظ بالإعدادات المستخدمة عند تحديد هذا الضغط. قم بتكوين كليهما قبل إضافة الصور ثنائية المستوى التي تريد ضغطها بهذه الطريقة

var
  Pdf: THotPDF;
begin
  Pdf := THotPDF.Create(nil);
  try
    Pdf.ImageCompressionType := icJBIG2;     // route 1-bit images through JBIG2
    Pdf.JBIG2Options.Lossless := True;        // keep every pixel
    Pdf.JBIG2Options.UseSymbolDictionary := True;
    Pdf.JBIG2Options.LossyLevel := 0;
    // Add pages and place your scanned 1-bit images here.
  finally
    Pdf.Free;
  end;
end;

من الميزات المريحة الجديرة بالملاحظة هي إضافة DBGridHotPDFExport، والتي تقوم بتقديم TDBGrid مباشرة إلى ملف PDF. مخرجاتها عبارة عن قواعد ونصوص ثنائية المستوى في الغالب، لذلك يحافظ المستند المهيأ لـ JBIG2 على إبقاء عمليات التصدير هذه مضغوطة دون أي معالجة إضافية من جانبك. هناك موضوعان مرتبطان في هذه المدونة يتعمقان في سير العمل المحيط. لمعرفة كيفية وضع الصور والخطوط عند إنشاء التقارير، راجع إخراج التقارير مع الخطوط والصور في Delphi. عندما يجب أن يلبي مستند مضغوط ملف تعريف أرشيفي، فإن القواعد الواردة في التحقق من صحة PDF/A و PDF/X و PDF/UA في Delphi تخبرك بالمرشحات التي يقبلها مستوى تطابق معين. يتم شحن JBIG2 كجزء من مكون HotPDF Component لـ Delphi و C++Builder، بجوار واجهات برمجة تطبيقات التحميل والتحرير والتشفير التي تمت تغطيتها في مكان آخر هنا