Naskenovaná zmluva je niekoľko stoviek bodov na palec čierneho atramentu na bielom papieri. Uložená ako bitová mapa s jedným bitom na pixel je už sama o sebe malá, no sto takýchto stránok stále nafúkne PDF nad rámec toho, čo by ste odoslali e-mailom. Správny filter zmení aritmetiku. JBIG2 je komprimácia s najvyšším pomerom, ktorú norma ISO 32000-1 definuje pre dvojúrovňové obrázky, a pri skupinách naskenovaného textu rutinne znižuje veľkosť na polovicu oproti tomu, čo produkuje CCITT Group 4. Toto je filter, po ktorom siahnete, keď vstup pochádza z faxu, skenera alebo je inak redukovaný na dve farby, a HotPDF ho dokáže priamo zapísať do PDF
Formát dosahuje tento pomer vďaka dvom myšlienkam, ktoré bežný obrázkový kodek nemá. Modeluje, ako čierne úseky ležia na bielom pozadí, a rozoznáva, že naskenovaná stránka pozostáva prevažne z niekoľkých stoviek rovnakých tvarov glyfov opakovaných tisíckrát. Pochopenie oboch aspektov vám umožní zámerne vyberať možnosti kódovania namiesto hádania
Kde sa JBIG2 nachádza v špecifikácii PDF
Norma ISO 32000-1 uvádza JBIG2Decode medzi filtruváciami streamov v §7.4.7, dostupné od PDF 1.4. Vzťahuje sa len na jedno miesto: obrazové objekty XObject, ktorých hodnota /BitsPerComponent je 1 a farebný priestor sa rozkladá na jediný kanál. To je celý zmysel. JBIG2 je dvojúrovňový kodek, takže nikdy nesúperí s DCT alebo JPXDecode pri fotografiách. Súperí s CCITTFaxDecode, faxovými filtrami Group 3 a Group 4, práve pri type dvojtónovej stránky, ktorú produkuje dokumentový skener
Dekodér spracúva vloženú organizáciu JBIG2, ktorú norma označuje ako PDF profil, kde každý obrazový stream obsahuje sekvenciu segmentov namiesto holého bitového toku. Voliteľný stream /JBIG2Globals prenáša segmenty zdieľané naprieč viacerými obrázkami v tom istom dokumente — to je mechanizmus, ktorý umožňuje uložiť opakujúci sa obsah raz pre celý súbor namiesto raz na stránku. HotPDF predvolene vysiela stream per-image a kanál globals nechá voľný, pokiaľ o to backend nepožiada
Architektúra kódovača s prioriotou backendu
Kompletný kódovač JBIG2 je rozsiahly softvér a jeho najagresívnejšie časti boli historicky zaťažené patentmi a distribuované pod licenciami, ktoré nevyhovujú každému produktu. HotPDF toto napätie rieši oddelením rozhrania od motora. Jednotka HPDFJBIG2 definuje volania, ktoré zvyšok knižnice vykonáva, a obsahuje skromný vstavaný kódovač, aby JBIG2 fungoval hneď po nainštalovaní. Keď potrebujete produkčné kompresné pomery, zaregistrujete silnejší motor a knižnica mu deleguje prácu bez akejkoľvek zmeny vo vašom kóde
Prepínanie sa vykoná jediným registračným volaním. Bez zaregistrovaného backendu kódovač spadne späť na vstavaný postup. Zaregistrujte ho a každé ďalšie kódovanie prebehne cez neho
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;
Rovnaký háčik existuje pre dekódovanie prostredníctvom RegisterJBIG2DecoderBackend, pričom IsJBIG2DecoderBackendAvailable slúži na jeho overenie. Preto knižnica dodáva malý vstavaný postup plus švík backendu namiesto jedného monolitického kódovača. Vstavaný postup udržuje binárny súbor štíhlym a oslobodeným od licenčných záväzkov, zatiaľ čo švík umožňuje tímu, ktorý si licencoval plný kódovač, zapojiť ho bez toho, aby sa vôbec dotýkal vrstvy zápisu PDF
Čo možnosti kódovania skutočne obchodujú
Kódovanie sa konfiguruje cez TJBIG2EncodeOptions, záznam s poliami Lossless, UseGlobalSegments, UseSymbolDictionary a LossyLevel. Obal priateľský ku komponentom THPDFJBIG2Options zverejňuje Lossless, UseSymbolDictionary a LossyLevel, aby ich bolo možné nastaviť z Inšpektora objektov, a interne ich prevádza na záznam. Tri zámery riadia nastavenia
Bezstratová rekonštrukcia zachováva každý pixel. Nastavte Lossless na True a nechajte LossyLevel na nule a dekódovaná bitmapa bude bit za bitom identická so vstupom. Toto je jediná bezpečná voľba pre čiarové umenie, technické výkresy a akúkoľvek stránku, kde by chýbajúci pixel mohol zmeniť význam, napríklad podpis alebo pečiatka. Kódovanie slovníka symbolov zapína deduplikáciu s vedomosťou textu a je voľbou, ktorá odlišuje JBIG2 od faxových filtrov. Stratová úroveň, celé číslo od 0 do 9, umožňuje schopnému backendu obchodovať vernosť za veľkosť tým, že skoro identické značky považuje za rovnaký symbol. Nula znamená bezstratové. Vstavaný kódovač rešpektuje len bezstratový postup a ignoruje akúkoľvek nenulovú stratovú úroveň, takže vyššie úrovne sa uplatnia až po zaregistrovaní backendu, ktorý ich implementuje
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;
Slovníky symbolov a prečo naskenovaný text vyhráva
Stránka naskenovaného textu nie je naozaj obrázok slov. Je to to isté písmeno e vytlačené niekoľko stokrát, to isté t, tá istá čiarka — každá výskyt je mierne zašumená kópia jedného základného tvaru. Slovník symbolov zachytáva túto štruktúru. Kódovač zhromažďuje odlišné značky na stránke do slovníka, každý tvar uloží raz a potom zaznamená stránku ako zoznam pozícií odkazujúcich na záznamy slovníka. Tisíc výskytov toho istého glyfu stojí jednu uloženú bitmapu plus tisíc lacných umiestnení
Práve tu JBIG2 predbehne CCITT Group 4. Group 4 kóduje každý riadok skenu oproti riadku nad ním bez akéhokoľvek pojmu o glyfe, takže platí plnú cenu každého písmena zakaždým, keď sa písmeno objaví. JBIG2 zaplatí raz. Keď sa rovnaký slovník povýši na stream globálov na úrovni dokumentu, úspora sa znásobuje naprieč viacestránkovým skenovaním, pretože tvary zdieľané stránkou za stránkou sú uložené jedenkrát pre celý súbor. Pri hustom texte nie je rozdiel okrajový. To je dôvod, prečo JBIG2 existuje
Všeobecná oblasť a MMR pre všetko ostatné
Nie každý dvojúrovňový obrázok je text. Mapy, schémy, technické výkresy a zmiešané stránky obsahujú čiarové umenie, ktoré žiadny slovník nedokáže zhrnúť. Pre tieto prípady JBIG2 kóduje všeobecnú oblasť — obdĺžnik pixelov komprimovaný priamo bez akéhokoľvek trénovania symbolov. Norma umožňuje všeobecnej oblasti používať MMR, modifikované modifikované READ kódovanie, ktoré fax Group 4 už používa a ktoré modeluje každý riadok pixelov oproti riadku nad ním
Toto je postup, ktorý HotPDF dodáva vo svojom vstavanom kódovači. Keď nie je zaregistrovaný žiadny backend a požiadavka je bezstratová, knižnica komprimuje bitmapu ako jedinú MMR všeobecnú oblasť a zabalí ju do štruktúry segmentov JBIG2 požadovanej PDF profilom. Nepotrebuje žiadny slovník, žiadny tréningový prechod ani žiadny druhý obrázok na referenciu, takže je spoľahlivým predvoleným pre čiarové umenie a zmiešaný dvojúrovňový obsah. Na čistom texte sa nevyrovná plnému kódovaču so slovníkom symbolov, ale je vždy správny, vždy bezstratový a vždy prítomný. Povrch kódovača pre neho je jedno volanie
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;
Zapnutie pri vytváraní dokumentu
Pri bežnom používaní sa triedy kódovača priamo nedotýkate. HotPDF sprístupňuje JBIG2 ako voľbu komprimácie obrázkov v dokumente. Enumerácia THPDFImageCompressionType zahŕňa icJBIG2 vedľa možností Flate, JPEG a CCITT, a dokument obsahuje vlastnosť JBIG2Options typu THPDFJBIG2Options, ktorá obsahuje nastavenia používané pri výbere tejto komprimácie. Nakonfigurujte oboje pred pridaním dvojúrovňových obrázkov, ktoré chcete takto komprimovať
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;
Jedna pohodlná funkcia, ktorú stojí za zmienku, je doplnok DBGridHotPDFExport, ktorý vykreslí TDBGrid priamo do PDF. Jeho výstup je prevažne dvojúrovňové čiary a text, takže dokument nakonfigurovaný pre JBIG2 udržiava tieto exporty kompaktné bez akéhokoľvek ďalšieho spracovania z vašej strany. Dve súvisiace témy na tomto blogu sa hlbšie venujú okolitému pracovnému postupu. Ako sa obrázky a písma ukladajú pri vytváraní zostáv nájdete v článku výstup zostavy s písomami a obrázkami v Delphi. Keď komprimovaný dokument musí spĺňať archivačný profil, pravidlá v článku validácia PDF/A, PDF/X a PDF/UA v Delphi vám povedia, ktoré filtre daná úroveň zhody akceptuje. JBIG2 je súčasťou HotPDF Component pre Delphi a C++Builder, vedľa rozhraní API pre načítanie, úpravu a šifrovanie, ktoré sú pokryté na iných miestach tu