مقال تقني

ضغط الصور ثنائية المستوى 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 فصاعدًا. ينطبق على مكان واحد فقط: XObjects للصور التي تكون /BitsPerComponent الخاصة بها 1 ومساحة ألوانها تحل إلى قناة واحدة. هذا هو بيت القصيد. JBIG2 هو برنامج ترميز ثنائي المستوى، لذلك فهو لا يتنافس أبدًا مع DCT أو JPXDecode على الصور الفوتوغرافية. يتنافس مع CCITTFaxDecode، وهي فلاتر فاكس Group 3 و Group 4، على نفس النوع من الصفحات ذات اللونين التي ينتجها ماسح المستندات

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

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

يعد مشفر 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 عن فلاتر الفاكس. يتيح مستوى الفقدان (lossy level)، وهو عدد صحيح من 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 مرة واحدة. عندما تتم ترقية نفس القاموس إلى تدفق globals على مستوى المستند، يتضاعف التوفير عبر مسح ضوئي متعدد الصفحات، لأن الأشكال التي تشترك فيها صفحة تلو الأخرى يتم تخزينها مرة واحدة للملف بأكمله. في النص الكثيف، لا يكون الفرق هامشياً. إنه السبب في وجود 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 لـ Delphi و C++Builder، بجوار واجهات برمجة تطبيقات التحميل والتحرير والتشفير التي يتم تناولها في مكان آخر هنا