PDF-funktiot ovat yksi spesifikaation hiljaisimmista kulmista. Useimmat kehittäjät kohtaavat ne kerran tyypin 2 aksiaalisen varjostuksen yhteydessä kahden värin välisen häivytyksen toteuttamiseksi, eivätkä katso niitä enää uudelleen. Se on sääli, koska funktiokoneisto on pieni yleiskäyttöinen arvioija, jota tiedostomuoto käyttää uudelleen varjostuksissa, siirtofunktioissa, rasteripistefunktioissa, erottelusävyissä ja pehmeän maskin siirtokäyrissä. Neljästä funktiotyypistä tyyppi 0 on tehokkain ja vähiten ymmärretty. Se on näytteistetty funktio: moniulotteinen ruudukko ulostuloarvoja, joiden välillä lukija interpoloi. Koska ruudukko voi sisältää mitä tahansa lukuja, tyypin 0 funktio voi ilmaista mielivaltaisen epälineaarisen kuvauksen, mikä on juuri värihakutaulukon (LUT) muoto.
Tässä artikkelissa käydään läpi tyypin 0 hakemisto (dictionary) sellaisena kuin ISO 32000-1 sen kohdassa §7.10.2 määrittelee, ja näytetään sitten kaksi tapausta, joilla on eniten merkitystä dokumenttiputkessa: kolmituloinen RGB-to-RGB-värikorjaus-LUT ja yksituloinen spottivärin sävymuunnos. Sama näytteistetyn funktion rakentaja palvelee molempia, ja niiden välinen ero on täysin kysymys siitä, kuinka monta tuloa ruudukossa on.
Näytteistetty funktio on ruudukko, jota lukija interpoloi
Tyypin 0 funktio kuvaa m-tuloisen vektorin n-lähtöiseksi vektoriksi tallentamalla näytteitä säännölliseen ruudukkoon ja interpoloimalla niiden välillä. ISO 32000-1 §7.10.2 luettelee avaimet, jotka kuvaavat tätä ruudukkoa. /Domain sisältää kaksi lukua tuloakselia kohti, eli kunkin tuloakselin alarajan ja ylärajan. /Range sisältää kaksi lukua lähtökomponenttia kohti. /Size on m kokonaisluvun taulukko, joka antaa näytteiden määrän kullakin tuloakselilla, joten ruudukolla, joka on kaksitoista näytettä sivultaan kolmessa ulottuvuudessa, on /Size [12 12 12] ja se tallentaa 1 728 ruudukon pistettä. /BitsPerSample asettaa kunkin tallennetun arvon tarkkuuden; HotPDF hyväksyy arvot 1, 2, 4, 8, 12, 16, 24 ja 32 bittiä, mikä vastaa taulukon 38 sallimia arvoja.
Näytevirtaa luetaan kiinteässä järjestyksessä. Ensimmäinen tuloulottuvuus vaihtelee nopeimmin, sitten toinen ja niin edelleen, ja jokaisessa ruudukon pisteessä n lähtökomponenttia tallennetaan järjestyksessä. RGB-to-RGB-taulukossa se on kolme tavua ruudukon pistettä kohti kahdeksalla bitillä, järjestettynä punainen-ulostulo, vihreä-ulostulo, sininen-ulostulo, pyyhkäisten ensin punaisen tulon yli. Kaksi muuta avainta kuvaavat jatkuvan maailman kokonaislukuruuduksi. /Encode kuvaa kunkin tulon /Domain-välistään näyteindeksialueelle 0 - Size[i] - 1, ja /Decode kuvaa tallennetut raa'at kokonaisluvut takaisin /Range-väleille. Kun ne jätetään oletusarvoihinsa, tulo välillä [0 1] osuu siististi koko ruudukkoon ja tallennettu tavu 255 dekoodautuu sen lähtöalueen huipulle, mikä on juuri sitä, mitä [0,1]-normalisoitu väri-LUT haluaa.
Order 1 verrattuna arvoon Order 3
Ruudukon pisteiden välillä lukijan on interpoloitava, ja /Order valitsee miten. /Order 1 on monilineaarinen interpolaatio: lineaarinen yhtä akselia pitkin, bilineaarinen kahden akselin yli, trilineaarinen kolmen akselin yli. Se on nopea, se on juuri sitä, mitä useimpien katseluohjelmien laitteisto tekee, ja tasaisessa värimuunnoksessa sitä on yleensä mahdoton erottaa hienommista menetelmistä. /Order 3 pyytää kuutiollista spline-interpolaatiota, joka sovittaa tasaisemman käyrän näytteiden läpi enemmän työn ja laajemman tukialueen kustannuksella kunkin arvioidun pisteen ympärillä.
Kompromissi on ruudukon tiheyden ja käyrän sileyden välillä. Kuutiollinen järjestys puolustaa paikkaansa, kun ruudukko on karkea ja kuvauksella on näkyvää kaarevuutta, koska suora viiva kahden etäisen näytteen välillä voi tasoittaa värisävykäyrää tavalla, jonka silmä havaitsee gradienteissa. Kun ruudukko on tiheä, segmentit ovat riittävän lyhyitä, jotta lineaarinen interpolaatio seuraa käyrää tiiviisti ja kuutiollinen tuo vähän hyötyä. Käytännön sääntö on turvautua arvoon /Order 3 vain pienillä ruudukoilla tai jyrkillä muunnoksilla ja jättää se muutoin lineaariseen oletukseen. Huomaa, että /Order koskee vain tyypin 0 funktioita, ja HotPDF hylkää kaikki muut arvot kuin 1 tai 3.
3D LUT: kolme tuloa, kolme lähtöä
RGB-to-RGB-värikorjaus on oppikirjaesimerkki kolmituloisesta ruudukosta, klassisesta 3D LUT -taulukosta, jota käytetään värikorjauksessa ja laitteiden sovituksessa. Kuution jokainen akseli on yksi tulokanava, jokainen ruudukon piste tallentaa korjatun RGB-kolmikon kyseiselle tulokoordinaatille, ja lukija interpoloi trilineäärisesti kulmanäytteet minkä tahansa saapuvan värin ympärillä. Kolme tuloa on tässä välttämätön, koska korjattu punainen voi riippua tulon vihreästä ja sinisestä, ei vain tulon punaisesta; kanavakohtainen käyrä ei voi ilmaista kanavien välistä ylikuulumista, mutta kuutio voi.
HotPDF rakentaa tyypin 0 virran RegisterSampledFunction-kutsulla, joka ottaa /Domain, /Range, /Size, /BitsPerSample ja näytetavut suoraan ja palauttaa funktio-objektin. Tavalliselle normalisoidulle kuutiolle välität [0,1]-rajat kaikilla kolmella tuloakselilla ja kaikilla kolmella lähdöllä, koon N x N x N ja litistetyn näytetaulukon. Rakentaja varmistaa, että tavumäärä vastaa ruudukkoa: tavuun kohdistetulle syvyydelle se odottaa arvoa OutputCount x (BitsPerSample div 8) x kokojen tulo, ja nostaa poikkeuksen, jos taulukko on väärän pituinen, joten väärin laskettu askellus epäonnistuu äänekkäästi rekisteröinnin yhteydessä sen sijaan, että se renderöityisi myöhemmin roskana.
const
N = 17; // 17 x 17 x 17 cube, the common ICC LUT resolution
var
LutFn: THPDFStreamObject;
Samples: TBytes;
begin
// Fill Samples with N*N*N grid points, 3 bytes each (R,G,B output),
// red input varying fastest. Build the corrected triple for each
// grid coordinate with your ICC-managed conversion, then store it.
SetLength(Samples, N * N * N * 3);
BuildCorrectedCube(Samples, N); // your color-managed fill
LutFn := Pdf.RegisterSampledFunction(
[0,1, 0,1, 0,1], // /Domain: three input axes on [0,1]
[0,1, 0,1, 0,1], // /Range: three output channels on [0,1]
[N, N, N], // /Size: the cube resolution per axis
8, // /BitsPerSample
Samples,
1); // /Order 1 = trilinear
end;
Kuution kolorimetrinen oikeellisuus riippuu siitä, miten täytät sen, ei PDF-funktiosta. Oikea tapa on laskea jokainen ruudukon piste ICC-ohjatun muunnoksen kautta, saman moottorin, joka ohjaa esikatselua, joten ruudukon luvuilla on merkitys määriteltyä lähde- ja kohdeprofiilia vasten. Rekisteröi muunnosta rajoittavat profiilit RegisterICCProfile-kutsulla, joka tallentaa ICCBased-väriavaruuden (1, 3 tai 4 komponenttia) ja palauttaa resurssinimen, jonka voit liittää sisältöön, jota LUT ruokkii. Tyypin 0 funktio kantaa interpolaatiotaulukkoa; ICC-profiili kantaa päätepisteiden merkityksen.
1D-tapaus: spottivärin sävymuunnos
Erotteluväriavaruudet tukeutuvat samaan koneistoon täysin eri työssä. Separation-avaruus, joka on määritelty ISO 32000-1 -standardin kohdassa §8.6.6.4, edustaa yksittäistä väriainetta, kuten Pantone- tai lakka-väriä, yhdistämällä nimen sävymuunnokseen: funktioon, joka kuvaa yksiulotteisen sävyarvon (0 ei väriä, 1 täysi väri) vaihtoehtoiseen väriavaruuteen, jonka laite voi todella renderöidä, yleensä CMYK:ksi. Kyseinen sävymuunnos on usein tyypin 0 funktio, ja nyt ruudukolla on täsmälleen yksi tuloakseli.
This is the clean contrast with the 3D LUT. Spottiväri on yksi vapaudenaste, joten sen sävymuunnos tarvitsee yhden tulon ja ruudukko on näyteviiva, joista kukin sisältää CMYK-arvon kyseisellä sävytasolla. RGB-kuutio tarvitsee kolme tuloa, koska sen toimialue on kolmiulotteinen ja kanavat vuorovaikuttavat. Sama funktiotyyppi, samat interpolaatiosäännöt, eri ulotteisuus; spesifikaatio käyttää uudelleen yhtä arvioijaa ja antaa /Size-määritteen päättää, käveletkö viivaa, tasoa vai kuutiota. HotPDF käärii koko erottelun RegisterSeparationLUT-kutsuun, joka rakentaa yksituloisen tyypin 0 sävymuunnoksen suoraan raa'asta tavutaulukosta sisäisesti ja palauttaa väriavaruusresurssin nimen.
var
SpotCS: AnsiString;
begin
// Four CMYK output bytes per tint grid point, tint domain [0..1].
// Here 0% ink -> all zero, 100% ink -> a rich spot build,
// with two interior steps; the tint transform interpolates between.
SpotCS := Pdf.RegisterSeparationLUT(
'PANTONE 286 C', // colorant name
'DeviceCMYK', // alternate color space
[ 0, 0, 0, 0, // tint 0.00 -> 0,0,0,0
90, 60, 0, 0, // tint 0.33
100, 80, 0, 10, // tint 0.66
100, 72, 0, 18]); // tint 1.00 -> full ink build
// Use SpotCS with SetFillColorSpace / SetFillColor on a page.
end;
Näytteiden määrän on oltava kokonainen määrä ruudukon pisteitä: positiivinen monikerta vaihtoehtoisen avaruuden komponenttimäärästä ja vähintään kaksi pistettä, jotta on olemassa segmentti interpoloitavaksi. Välitä kolme tavua pistettä kohti CMYK-vaihtoehtoa vasten ja kutsu hylkää sen, soveltaen samaa puolustavaa validointia kuin 3D-rakentaja, mikä on juuri sitä, mitä haluat toiminnolta, joka muuten epäonnistuisi hiljaa tulostusaikana.
Missä sama koneisto näkyy uudelleen
Kun näet tyypin 0 yleisenä interpolaatiotaulukon, kaksi muuta laiteohjausominaisuutta lakkaavat vaikuttamasta erikoistapauksilta. Siirtofunktio säätää komponenttien arvoja matkalla ulostulolaitteelle, ja se on vain kanavakohtainen funktio; HotPDF rekisteröi sen ExtGState-tilana RegisterTransferFunctionState-kutsun kautta, joka hyväksyy joko yhden yhdistetyn funktion tai kanavakohtaisten funktioiden taulukon. Koska nämä funktiot ovat tavallisia funktio-objekteja, voit antaa sille juuri sen THPDFStreamObject-objektin, jonka RegisterSampledFunction palauttaa, ja ohjata siirtokäyrää näytteistetystä taulukosta kaavan sijaan.
var
ToneFn: THPDFStreamObject;
GsName: AnsiString;
begin
// A single-input, single-output sampled tone curve on [0,1].
ToneFn := Pdf.RegisterSampledFunction(
[0,1], [0,1], [256], 8, ToneCurveBytes, 1);
// Apply it to all channels as a combined /TR2 transfer function.
GsName := Pdf.RegisterTransferFunctionState(ToneFn, []);
// Select GsName on the page before drawing the affected content.
end;
Mustan muodostus ja alavärin poisto istuvat samassa perheessä. Kun laite muuntaa RGB:n CMYK:ksi, se päättää, kuinka paljon harmaakomponenttia kuljetetaan mustana musteena, ja spesifikaatio ilmaisee tämän päätöksen funktiona, eli grafiikkatilan sanakirjan /BG2- ja /UCR2-merkintöinä, joista kukin on yksituloinen käyrä lasketusta harmaasta mustan määrään. Nämäkin ovat tyypin 0 funktioita, kun haluat mitatun käyrän analyyttisen sijaan, ja ne rakennetaan samalla tavalla RegisterSampledFunction-kutsun kautta ja asetetaan grafiikkatilaan. Muistamisen arvoinen opetus on se, että PDF-funktio ei ole koskaan se paikka, jossa värinhallinta tapahtuu; se on hakutaulukko, joka kuljettaa todellisella värimoottorilla tekemäsi päätöksen, ja tyyppi 0 on ainoa funktiotyyppi, joka on tarpeeksi joustava kantamaan minkä tahansa päätöksen.
Laajemmasta kuvasta siitä, miten fontit, kuvat ja väriresurssit viedään valmiiseen dokumenttiin, on tietoa ohjeessamme raporttien tuottamisesta fonteilla ja kuvilla. Kun tulosteen on selviydyttävä arkisto- tai tulostusesitarkastuksesta, väriavaruus- ja tulostusaikomussäännöt, jotka käsitellään PDF/A-, PDF/X- ja PDF/UA-validointioppaassa, määräävät, mitkä näistä funktioista ovat sallittuja ja miten laitteen väri on merkittävä. Kaikki tämä toimitetaan Delphin ja C++Builderin HotPDF Componentissa samalle tyypin 0 ytimelle rakentuvien varjostus-, ICC- ja erottelu-API:en rinnalla.