Skannattu lääketieteellinen dia, ilmakuvausruutu, filmiruutu arkistoituna koko dynaamiselle alueelle. Nämä ovat kuvia, jotka saapuvat JPEG 2000:na, ja ne saapuvat siihen suuntaan syystä. Muoto säilyttää 12 tai 16 bittiä kanavaa kohti, pakkaa aallokemuunnoksella JPEG:n käyttämän lohko DCT:n sijaan ja pystyy koodaamaan saman kuvan joko häviöttömänä tai häviöllisenä yhdestä koodivirrasta. Kun niistä lähteistä rakennetusta asiakirjasta tulee PDF, kuvan on kuljettava suodattimen läpi, jonka PDF-määritys varaa juuri tätä koodekkia varten
HotPDF v2.228.0 palautti toimivan JPEG 2000 -purkumoottorin kyseiselle tielle. Aiemmassa koontiversiossa yksikkö toimitettiin tynkätoiminnoilla, jotka palauttivat koodin nil, joten API oli olemassa, mutta ei purkanut mitään. Nykyinen moottori sitoo OpenJPEG 2.5.4:n staattisesti ja muuttaa JP2- tai J2K-lähteen pikseleiksi, jotka HotPDF voi sijoittaa sivulle
JPXDecode-suodatin PDF-muodossa
ISO 32000-1 määrittelee JPXDecode-suodattimen kohdassa 7.4.9. PDF-kuvan XObject nimeää pakkauksensa virtasanakirjan /Filter-kohteessa, ja JPXDecode on arvo, joka sanoo, että virran data on JPEG 2000 -koodivirta pikemminkin kuin perusviivan JPEG, jota /DCTDecode sisältää. Suodatin on se, mikä sallii PDF:n säilyttää aallokepakattua kuvadataa, jolla on suuri bittisyvyys, ja se sallii sekä koodekin häviöttömän että häviöllisen tilan, koska tila on itse koodivirran, ei sen ympärillä olevan kääreen ominaisuus
Se viimeinen seikka on pitämisen arvoinen. JPEG 2000 on yksi algoritmi häviöttömällä erikoistapauksella, ei kahta erillistä muotoa. Käännettävä 5/3 aalloke rekonstruoi alkuperäiset näytteet tarkalleen; peruuttamaton 9/7-aalloke vaihtaa kyseisen tarkkuuden pienempään tiedostoon. Dekooderi käsittelee molempia samalla tavalla lukuhetkellä, minkä vuoksi HotPDF tarvitsee vain yhden purkupolut hyväksyäkseen sen, mitä tahansa JPXDecode-virta heittääkään siihen
Mitä dekooderi tekee pikseleille
PDF-kuvan XObjects odottavat tavallisesti 8 bittiä per komponentti DeviceGray:ssä tai DeviceRGB:ssä. JPEG 2000 ylittää säännöllisesti sen, ja sen komponenttimalli on yleisempi kuin pakattu rasteri, joten dekooderilla on kolme työtä tehtävänä, ennen kuin data on käytettävissä normaalikuvana
Ensin korkean bittisyvyyden komponentit otetaan uudelleen 8 bittiin. 12- tai 16-bittinen näyte pienennetään alueelle 0-255 siten, että tuloksena on tavallinen 8-bittinen rasteri. Allekirjoitetut komponentit siirretään ensin allekirjoittamattomalle alueelle. Yksityiskohdalla on merkitystä, koska se itsessään on häviöllinen: 16-bittinen harmaasävyskannaus menettää syvän sävyalueensa heti, kun siitä tulee 8-bittinen PDF-kuva, mikä on oikea kompromissi näytön ja tulostuksen suhteen, mutta ei uudelleen arkistoinnille
Toiseksi YCbCr (koodekki kutsuu sitä nimellä SYCC) -väriavaruus muunnetaan RGB:ksi. JPEG 2000 tallentaa usein värit luminanssiväriavaruuteen pakkauksen tehostamiseksi. Tämä on sama ajatus, jota perus-JPEG käyttää, ja dekooderi soveltaa standardia käänteistä muunnosta, jotta sivu saa aidon RGB:n
Kolmanneksi alinäytteenotetuista komponenteista otetaan näyte lähimmän naapurin replikaatiolla. Kromakanavat tallennetaan usein puolet tarkkuudella, joten dekooderi lukee jokaisen komponentin sen omilla mitoilla ja omalla näytteenottokertoimellaan ja kopioi sitten näytteitä tuodakseen jokaisen kanavan täyteen kuvan kokoon ennen lomitusta. Lähin naapuri pitää askeleen halpana; kromi, jota se täytti, oli alun alkaen matalataajuista, joten näkyvät kustannukset ovat pienet
JP2-laatikot verrattuna raaka-J2K-koodivirtaan
JPEG 2000 -tiedosto on kahdessa muodossa, ja HotPDF havaitsee kumpaa se lukee ensimmäisistä tavuista tiedostopäätteen sijaan. JP2-tiedosto on laatikkostrukturoitu säiliö: se avautuu kahdentoista tavun allekirjoituslaatikolla 00 00 00 0C 6A 50 20 20 ja käärii koodivirran laatikoiden rinnalle, jotka kuvaavat väriavaruutta, resoluutiota ja metadataa. Raaka J2K-koodivirta ei sisällä ollenkaan konttia, ja alkaa SOC-merkillä FF 4F FF 51. Dekooderi lukee nuo etutavut, tunnistaa allekirjoituksen ja valitsee kussakin tapauksessa vastaavan OpenJPEG-koodekin
Molemmat muodot käsitellään, koska molempia esiintyy luonnossa. Kaappaa laitteet ja arkistot, jotka tarvitsevat sivumetatietoja lähettävät JP2:n; työkalut, jotka haluavat pienimmän mahdollisen hyötykuorman, lähettävät paljaan koodivirran. Muototyyppi on mallinnettu enumina, TJpeg2000FileType, ja siinä on jäsenet jtInvalid, jtJP2, jtJ2K ja jtJPT. JPT-jäsen nimeää JPIP-suoratoistoversion; tavuallekirjoitusilmaisin ratkaisee kaksi sen purkamaa muotoa, JP2:n ja J2K:n, ja raportoi kaiken muun kuin jtInvalid, jotta ei-tuettu syöte epäonnistuu puhtaasti roskan tuottamisen sijaan
uses
HPDFJpeg2000;
var
Decoder: THPDFJpeg2000Decoder;
Pixels: TJpeg2000ByteArray;
begin
Decoder := THPDFJpeg2000Decoder.Create;
try
if Decoder.LoadFromStream(Input) then // JP2 tai J2K, automaattisesti tunnistettu
if Decoder.GetImageData(Pixels) then
// Pixels on 8-bittinen lomitettu, ColorComponents -kanavien leveä,
// rivitason tärkeimmät ylhäältä alas: valmiina DeviceGray/DeviceRGB XObjectille.
ProcessRaster(Decoder.Width, Decoder.Height,
Decoder.ColorComponents, Pixels);
finally
Decoder.Free;
end;
end;
Häviötön ja häviöllinen koodauspuolella
Dekooderi lukee molemmat tilat kertomatta kumpi on. Valinta muodostuu vain parametriksi, kun menet toiseen suuntaan ja tuotat JPEG 2000 -tiedoston, jonka HotPDF voi tehdä myös TJpeg2000Bitmap-luokan kautta, joka on TBitmap-jälkeläinen, joka lataa ja tallentaa rasteritiedot JP2:na. Kaksi ominaisuutta ohjaa tulostetta. LosslessCompression on boolen arvo, joka valitsee palautuvan aallon, kun se on tosi; CompressionQuality on koodi TJpeg2000QualityRange, kokonaisluku väliltä 1-100, jossa 1 on pieni ja ruma ja 100 on suuri ja uskollinen. Oletukset asuvat nimetyissä vakioissa: Jpeg2000DefaultLosslessCompression on False ja Jpeg2000DefaultLossyQuality on 80
Päätös on sisältöpäätös. Lossless sopii pääkopioon, lääketieteelliseen tai juridiseen skannaukseen, mihin tahansa sellaiseen, joka voidaan koodata myöhemmin uudelleen ja joka ei saa kerääntyä sukupolvitappiota. Häviöllinen laatuluokassa 80 sopii kuvalle suunnatulle ruudulle tai tulostukselle, jossa aallokkeen siro huonontuminen tuottaa huomattavasti pienemmän tiedoston ilman artefakteja, jotka lukija huomaisi. Varoituksena on yksi CMYK-varoitus: bittikartta paljastaa komennon SetCMYK, joka merkitsee nelikanavaisen datan CMYK:ksi RGBA:n sijaan, jolla on merkitystä painoputkissa, jotka pitävät erottelut ennallaan
uses
HPDFJpeg2000;
var
Bmp: TJpeg2000Bitmap;
begin
Bmp := TJpeg2000Bitmap.Create;
try
Bmp.LoadFromStream(Source); // pura olemassa oleva JP2/J2K
Bmp.LosslessCompression := True; // palautuva 5/3 aalloke
// tai pienempi häviöllinen tiedosto:
// Bmp.LosslessCompression := False;
// Bmp.CompressionQuality := 80; // vastaa oletusasetusta
Bmp.SaveToStream(Output); // kirjoittaa aina JP2-tiedoston
finally
Bmp.Free;
end;
end;
Miksi latauksella purkavaa suodatinputkistoa ei ole
Yksi arkkitehtoninen tosiasia muokkaa sitä, miten käytät mitä tahansa näistä, ja päinvastoin on helppo olettaa. HotPDF:ssä ei ole yleistä lataamalla purettavaa kuvasuodatinta. Kun avaat PDF-tiedoston, joka sisältää jo JPXDecode-kuvan, moottori ei pura kyseistä virtaa. Se pitää JPEG 2000 -tavut täsmälleen sellaisina kuin ne ovat, joten sivu kopio tai dokumentin yhdistäminen kantaa kuvan läpi koskemattomana, tavu tavulta. Dekooderissa on yksi tulopiste, ja se on luomispuolella: tiedostopohjainen koodi AddImage, joka lähetetään tiedostotunnisteen kautta käsittelemään kohteita .jp2, .j2k, .jpt ja .jpc lähdettä
Tuo jako on oikea rakenne rajoituksen sijaan. Upotetun JPX-virran purkaminen latauksen yhteydessä ja sen koodaaminen uudelleen tallennuksen yhteydessä muuttaisi häviöttömän arkistoidun kuvan häviölliseksi ja paisuttaisi jokaisen yhdistämisen, kaikki kuvalle, jonka tarkoituksena oli vain siirtää PDF-tiedostosta toiseen. Virran ohittaminen sellaisenaan on häviötön ja nopea toiminta. Dekoodaus lykätään ainoaan hetkeen, jolloin sitä aidosti tarvitaan: kun ojennat koneelle JPEG 2000 -tiedoston levyltä ja pyydät sitä rasteroimaan kyseisen kuvan uudelle sivulle sijoittamista varten. Tässä vaiheessa tiedostosta on tultava pikseleitä ja dekooderi on käynnissä
Tuen rekisteröiminen ja kuvan sijoittaminen
JPEG 2000 -kuvien rekisteröinti on sallittava kääntökytkimen HPDF_REGISTER_JPEG2000_PICTURE takana, joka on oletuksena pois päältä. Syynä on todellinen konflikti, ei varovaisuus: tiedostomuotojen jp2, j2k ja jpc rekisteröiminen globaalisti komennolla TPicture voi häiritä ReportBuilderin komennon TppDBImage perustuvaa BLOB-muodon tunnistusta. Määritä kytkin, kun tuo integrointi ei ole pelissä, ja tiedostomuodot rekisteröidään niin koodi TPicture tunnistaa ne; jätä se määrittelemättä ja komennon AddImage laajennuksen lähetys purkaa JPEG 2000 -tiedostot suoraan, koska tämä polku ei mene ollenkaan komennon TPicture kautta
Tämän ymmärtäen JPEG 2000 -kuvan sijoittaminen tapahtuu samanlaisella kolmen puhelun rytmillä kuin mikään muukin HotPDF-kuva. Anna parametrille AddImage koodi .jp2-polku ja pakkaustyyppi sen määrittämiseksi, kuinka kuva tallennetaan tulostukseen, ja sijoita sitten palautettu kuvahakemisto sivulle komennolla ShowImage
var
Pdf: THotPDF;
ImgIndex: Integer;
begin
Pdf := THotPDF.Create(nil);
try
Pdf.BeginDoc;
Pdf.AddPage;
// .jp2-lähde puretaan OpenJPEG-taustaosan kautta, sitten
// upotettu uudelleen tässä pyytämälläsi pakkauksella.
ImgIndex := Pdf.AddImage('Scan_16bit.jp2', icJpeg);
// x, y, leveys, korkeus pisteinä; lopullinen 0 on kiertokulma.
Pdf.ShowImage(ImgIndex, 72, 72, 400, 300, 0);
Pdf.EndDoc;
finally
Pdf.Free;
end;
end;
Koodille AddImage antamasi pakkaus ohjaa sitä, kuinka dekoodattu kuva tallennetaan uudelleen, ei sitä, kuinka se on luettu. Bittikartaksi dekoodattu JPEG 2000 -tiedosto voi palata DCTDecode JPEG -muodossa, Flate-rasterina tai muuna tuettuna suodattimena, kumpi tahansa asiakirjaan sopii. Purkaminen koodista JP2 tai J2K tapahtuu kuitenkin ensin, joten sama puhelu hyväksyy aallokepakatun lähteen ja upottaa sen missä tahansa muodossa muu putki odottaa
Saat laajemman kuvan siitä, kuinka kuvat ja fontit osuvat tuotettuihin tulosteisiin, katsomalla muistiinpanomme raportin ulostulosta, jossa on fontteja ja kuvia. Kun kokoamassasi asiakirjassa käytetään uudelleen olemassa olevien PDF-tiedostojen sisältöä, tässä kuvattu läpivientikäyttäytyminen on pariliitos komennon objektivirrat ja inkrementaaliset päivitykset yhdistämis- ja versiomekaniikan kanssa. JPEG 2000 -purkumoottori toimitetaan osana Delphin ja C++Builderin HotPDF Component -osana muualla tässä blogissa käsiteltyjen kuva-, fontti- ja dokumentti-sovellusliittymien ohella