Ett skannat kontrakt består av några hundra punkter per tum svart bläck på vitt papper. Lagrat som en bitmapp med en bit per pixel är det redan litet, men hundra sådana sidor blåser ändå upp en PDF till mer än vad du skulle skicka via e-post. Rätt filter förändrar matematiken. JBIG2 är den komprimering med högst ratio som ISO 32000-1 definierar för svartvita bilder, och för en bunt skannad text halverar det rutinmässigt vad CCITT Group 4 producerar. Detta är filtret att sträcka sig efter när inmatningen faxas, skannas eller på annat sätt reduceras till två färger, och HotPDF kan skriva in det direkt i en PDF
Formatet förtjänar denna ratio med två idéer som en generisk bild-codec inte har. Det modellerar hur svarta linjer sitter mot en vit bakgrund, och det uppmärksammar att en skannad sida oftast är samma par hundra teckenformer som upprepas tusentals gånger. Att förstå båda är vad som låter dig välja kodningsalternativ medvetet i stället för att gissa
Var JBIG2 befinner sig i PDF-specifikationen
ISO 32000-1 listar JBIG2Decode bland strömfiltren i §7.4.7, tillgängligt från PDF 1.4 och framåt. Det gäller bara på ett ställe: bild-XObjects vars /BitsPerComponent är 1 och vars färgrymd löses till en enda kanal. Det är hela poängen. JBIG2 är en svartvit codec, så den konkurrerar aldrig med DCT eller JPXDecode på fotografier. Den konkurrerar med CCITTFaxDecode, faxfiltren i Group 3 och Group 4, på exakt den typ av tvåtonssida som en dokumentskanner producerar
Avkodaren konsumerar den inbäddade JBIG2-organisationen som standarden kallar PDF-profilen, där varje bildström rymmer en sekvens av segment i stället för en ren bitström. En valfri /JBIG2Globals-ström bär segment som delas över flera bilder i samma dokument, vilket är mekanismen som låter upprepat innehåll lagras en gång för en hel fil i stället för en gång per sida. HotPDF matar ut strömmen per bild som standard och håller den globala kanalen fri såvida inte en backend begär den
Backend-först arkitektur för kodare
En komplett JBIG2-kodare är en stor programvara, och de mest aggressiva delarna av den har historiskt sett belastats av patent och levererats under licenser som inte passar alla produkter. HotPDF löser denna spänning genom att skilja gränssnittet från motorn. Enheten HPDFJBIG2 definierar de anrop som resten av biblioteket gör, och den levereras med en blygsam inbyggd kodare så att JBIG2 fungerar direkt från start. När du behöver produktionsmässig komprimering registrerar du en starkare motor och biblioteket delegerar till den, utan ändringar i din anropande kod
Växlingen är ett enda registreringsanrop. Utan någon backend registrerad, faller kodaren tillbaka på sin inbyggda väg. Registrera en och varje efterföljande kodning körs genom den
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;
Samma krok existerar för avkodning genom RegisterJBIG2DecoderBackend, med IsJBIG2DecoderBackendAvailable för att kontrollera den. Detta är anledningen till att ett bibliotek levereras med en liten inbyggd väg plus en backend-söm i stället för en monolitisk kodare. Den inbyggda vägen håller den binära filen mager och fri från licensförvecklingar, medan sömmen låter ett team som har licensierat en fullständig kodare ansluta den utan att röra PDF-skrivarlagret alls
Vad kodningsalternativen faktiskt byter bort
Kodningen konfigureras genom TJBIG2EncodeOptions, en post med fälten Lossless, UseGlobalSegments, UseSymbolDictionary och LossyLevel. Den komponentvänliga inpackningen THPDFJBIG2Options publicerar Lossless, UseSymbolDictionary och LossyLevel så att de kan ställas in från Object Inspector, och den konverterar till posten internt. Tre avsikter driver inställningarna
Förlustfri rekonstruktion behåller varje pixel. Sätt Lossless till True och lämna LossyLevel på noll, och den avkodade bitmappen är bit för bit identisk med inmatningen. Detta är det enda säkra valet för linjekonst, tekniska ritningar och varje sida där en borttappad pixel skulle kunna ändra betydelsen, såsom en signatur eller en stämpel. Symbolordsbokskodning slår på textmedveten deduplicering och är det alternativ som skiljer JBIG2 från faxfiltren. Förlustnivån, ett heltal från 0 till 9, låter en kapabel backend byta trohet mot storlek genom att behandla nästan identiska märken som samma symbol. Noll betyder förlustfritt. Den inbyggda kodaren respekterar bara den förlustfria vägen och ignorerar varje förlustnivå skild från noll, så de högre nivåerna träder i kraft först när en backend som implementerar dem är registrerad
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;
Symbolordsböcker och varför textskanningar vinner
En sida med skannad text är egentligen inte en bild av ord. Det är samma bokstav e utskriven flera hundra gånger, samma t, samma komma, varje instans en aningen brusig kopia av en underliggande form. En symbolordsbok fångar den strukturen. Kodaren samlar de distinkta märkena på sidan i en ordbok, lagrar varje form en gång och registrerar sedan sidan som en lista över positioner som refererar till ordboksposter. Ett tusen förekomster av samma tecken kostar en lagrad bitmapp plus ett tusen billiga placeringar
Detta är precis var JBIG2 drar ifrån CCITT Group 4. Group 4 kodar varje skanningslinje mot linjen ovanför den utan någon uppfattning om ett tecken, så den betalar hela kostnaden för varje bokstav varje gång bokstaven dyker upp. JBIG2 betalar en gång. När samma ordbok lyfts fram till dokumentnivåns globala ström, multipliceras besparingen över en skanning på flera sidor, eftersom de former som delas av sida efter sida lagras en enda gång för hela filen. För tät text är skillnaden inte marginell. Det är anledningen till att JBIG2 existerar
Generisk region och MMR för allt annat
Inte varje svartvit bild är text. Kartor, scheman, tekniska ritningar och blandade sidor har linjekonst som ingen ordbok kan sammanfatta. För dessa kodar JBIG2 en generisk region, en rektangel av pixlar som komprimeras direkt utan någon symbolträning. Standarden tillåter en generisk region att använda MMR, den modifierade modifierade READ-kodningen som Group 4 fax redan använder, vilken modellerar varje rad av pixlar mot raden ovanför den
Detta är vägen som HotPDF levererar i sin inbyggda kodare. När ingen backend är registrerad och begäran är förlustfri, komprimerar biblioteket bitmappen som en enda generisk MMR-region och slår in den i den JBIG2-segmentstruktur som PDF-profilen kräver. Den behöver ingen ordbok, inget träningspass och ingen andra bild att referera till, så det är den pålitliga standarden för linjekonst och blandat svartvitt innehåll. Den kommer inte att matcha en fullständig kodare med symbolordsbok på ren text, men den är alltid korrekt, alltid förlustfri och alltid närvarande. Kodningsytan för den är ett anrop
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;
Att slå på det när du bygger ett dokument
För vardagligt bruk rör du inte kodarklassen direkt. HotPDF exponerar JBIG2 som ett bildkomprimeringsval i dokumentet. Uppräkningen THPDFImageCompressionType inkluderar icJBIG2 vid sidan av alternativen Flate, JPEG och CCITT, och dokumentet bär på en JBIG2Options-egenskap av typen THPDFJBIG2Options som håller de inställningar som används när den komprimeringen väljs. Konfigurera båda innan du lägger till de svartvita bilder du vill ha komprimerade på detta sätt
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;
En bekvämlighet värd att notera är DBGridHotPDFExport-tillägget, vilket renderar en TDBGrid rakt in i en PDF. Dess utmatning består till stor del av svartvita linjer och text, så ett dokument konfigurerat för JBIG2 håller dessa exporter kompakta utan någon extra hantering från din sida. Två relaterade ämnen på denna blogg går djupare in i det omgivande arbetsflödet. För hur bilder och teckensnitt läggs ut när du bygger rapporter, se rapportutmatning med teckensnitt och bilder i Delphi. När ett komprimerat dokument måste uppfylla en arkiveringsprofil, berättar reglerna i PDF/A, PDF/X och PDF/UA-validering i Delphi vilka filter en given överensstämmelsenivå accepterar. JBIG2 levereras som en del av HotPDF Component för Delphi och C++Builder, bredvid de API:er för laddning, redigering och kryptering som täcks på andra ställen här