Сканиран договор представлява няколкостотин точки на инч черно мастило върху бяла хартия. Записан като битмап с един бит на пиксел, той вече е малък, но сто такива страници все пак раздуват PDF файл до размер, неподходящ за изпращане по имейл. Правилният филтър променя изчисленията коренно. JBIG2 е компресията с най-висок коефициент, която ISO 32000-1 дефинира за двуцветни изображения, и при купчина сканиран текст тя редовно постига наполовина по-малък размер спрямо CCITT Group 4. Това е филтърът, към който трябва да посегнете, когато входните данни са получени по факс, сканирани или по друг начин сведени до два цвята, а HotPDF може да го запише директно в PDF
Форматът постига своя коефициент чрез две идеи, липсващи в обикновените кодеци за изображения. Той моделира как черните участъци стоят върху бял фон, и забелязва, че сканираната страница се състои предимно от едни и същи няколкостотин форми на знаци, повторени хиляди пъти. Разбирането и на двете ви позволява да избирате опциите за кодиране съзнателно, вместо на сляпо
Мястото на JBIG2 в PDF спецификацията
ISO 32000-1 включва JBIG2Decode сред поточните филтри в §7.4.7, наличен от PDF 1.4 нататък. Той се прилага само на едно място: image XObject обекти, чийто /BitsPerComponent е 1 и чието цветово пространство се свежда до един канал. Точно в това е смисълът. JBIG2 е двуцветен кодек и никога не се конкурира с DCT или JPXDecode при снимки. Той се конкурира с CCITTFaxDecode, филтрите за факс Group 3 и Group 4, именно при страниците с два тона, каквито произвежда документен скенер
Декодерът обработва вградената JBIG2 организация, която стандартът нарича PDF профил, при която всеки поток от изображения съдържа поредица от сегменти, а не необработен битов поток. Незадължителен поток /JBIG2Globals съдържа сегменти, споделени между няколко изображения в един документ, което е механизмът, позволяващ повтарящото се съдържание да се съхранява веднъж за целия файл, а не веднъж на страница. HotPDF по подразбиране генерира поток за отделното изображение и оставя канала за глобалните данни свободен, освен ако бекенд не ги поиска
Архитектура с приоритет на бекенда
Пълен JBIG2 encoder е обемно парче софтуер, а най-агресивните му части исторически са били обременени с патенти и разпространявани под лицензи, неподходящи за всеки продукт. HotPDF решава това противоречие, като разделя интерфейса от двигателя. Модулът HPDFJBIG2 дефинира повикванията, които останалата библиотека извършва, и включва скромен вграден encoder, така че JBIG2 работи от кутията. Когато ви трябват производствени коефициенти, регистрирате по-мощен двигател и библиотеката делегира задачата към него, без никаква промяна в кода ви
Превключването е едно-единствено регистрационно повикване. Без регистриран бекенд encoder използва вградения си path. Регистрирайте един и всяко следващо кодиране минава през него
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 за проверка. Именно затова библиотеката включва малък вграден path плюс шев за бекенд, вместо един монолитен encoder. Вграденият path поддържа двоичния файл компактен и свободен от лицензни усложнения, докато шевът позволява на екип, лицензирал пълен encoder, да го включи, без да докосва слоя за запис на PDF
Какво реално разменят опциите за кодиране
Кодирането се конфигурира чрез TJBIG2EncodeOptions, запис с полетата Lossless, UseGlobalSegments, UseSymbolDictionary и LossyLevel. Обвивката THPDFJBIG2Options, удобна за компоненти, публикува Lossless, UseSymbolDictionary и LossyLevel, за да могат да се задават от Object Inspector, и вътрешно ги преобразува в записа. Три намерения управляват настройките
Безпотребното пресъздаване запазва всеки пиксел. Задайте Lossless на True и оставете LossyLevel на нула и декодираният битмап ще бъде бит по бит идентичен с входните данни. Това е единственият безопасен избор за линейна графика, технически чертежи и всяка страница, при която изпуснат пиксел би могъл да промени смисъла, като подпис или печат. Кодирането с речник на символите включва дедупликация, отчитаща текст, и е опцията, която отличава JBIG2 от факс филтрите. Нивото на загуба, цяло число от 0 до 9, позволява на способен бекенд да разменя точност срещу размер, третирайки почти идентични знаци като един символ. Нула означава без загуба. Вграденият encoder спазва само пътя без загуба и игнорира всяко ненулево ниво на загуба, така че по-високите нива влизат в сила само след като бъде регистриран бекенд, который ги прилага
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;
Речници на символите и защо сканираният текст печели
Страница сканиран текст всъщност не е изображение на думи. Тя е буквата е, отпечатана няколкостотин пъти, същата т, същата запетая, всеки екземпляр е леко зашумено копие на една основна форма. Речникът на символите улавя тази структура. Encoder-ът събира отделните знаци на страницата в речник, съхранява всяка форма веднъж, а след това записва страницата като списък от позиции, препращащи към записи в речника. Хиляда появявания на един и същи глиф струват един съхранен битмап плюс хиляда евтини позиции
Точно тук JBIG2 изпреварва CCITT Group 4. Group 4 кодира всеки ред от скенера спрямо реда над него, без никакво понятие за глиф, затова плаща пълната цена за всяка буква при всяко нейно появяване. JBIG2 плаща веднъж. Когато същият речник бъде издигнат до глобалния поток на ниво документ, спестяването се натрупва при многостранично сканиране, тъй като формите, споделени от страница на страница, се съхраняват само веднъж за целия файл. При плътен текст разликата не е незначителна. Тя е причината JBIG2 да съществува
Общи региони и MMR за всичко останало
Не всяко двуцветно изображение е текст. Карти, схеми, технически чертежи и смесени страници съдържат линейна графика, която никой речник не може да обобщи. За тях JBIG2 кодира общ регион, правоъгълник от пиксели, компресиран директно без никакво обучение по символи. Стандартът разрешава общ регион да използва MMR, модифицираното модифицирано READ кодиране, което факсът Group 4 вече използва и което моделира всеки ред пиксели спрямо реда над него
Това е пътят, включен в вградения encoder на HotPDF. Когато не е регистриран бекенд и заявката е без загуба, библиотеката компресира битмапа като единичен общ MMR регион и го обвива в структурата от JBIG2 сегменти, изисквана от PDF профила. Той не се нуждае от речник, от обучителна стъпка, нито от второ изображение за справка, затова е надеждното значение по подразбиране за линейна графика и смесено двуцветно съдържание. Той не може да се мери с пълен encoder с речник на символите при чист текст, но винаги е коректен, без загуби и винаги наличен. Encoder интерфейсът за него е едно повикване
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;
Активиране при изграждане на документ
При ежедневна употреба не докосвате директно класа encoder. 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, наред с API-тата за зареждане, редактиране и криптиране, разгледани другаде тук