Tehnični članak

Jedra zmanjševanja slik HotPDF in rastriranje za tisk

HotPDF izpostavi tri jedra za zmanjševanje slik skozi lastnost ImageDownsampleKernel in ločeno potezo Floyd-Steinberg skozi RenderOutputDither. Prvo nadzoruje, kako fotografije izgledajo, potem ko jih skrčite, da zadete proračun velikosti, drugo pa, kako izgledajo, potem ko je stran zreducirana na črno-belo. Nobeno ni privzeto vklopljeno in obe sta odopt-in iz istega razloga: staneta pravi čas

Pritisk, ki ljudi pripelje sem, je znan. Skenirana pogodba 60 MB mora ven skozi poštni prehod, ki zavrne karkoli nad 10 MB, ali pa mora paket izpiskov pristati na faksu podobni monokromski napravi, ki vsak siv piksel izriše kot papir ali toner. Obe težavi sta težavi prevzorčenja in imata hitri odgovor, ki izgleda slabo, in počasnega, ki izgleda prav

Čim se tri jedra dejansko razlikujejo

THPDFResampleKernel ima tri vrednosti in one sedejo na resnično različnih točkah krivulje hitrosti in kakovosti. rkHalftone se prenese na zgodovinsko pot GDI StretchBlt z načinom HALFTONE, ki je kljub imenu filtriranje razreda bilinear: hitro, zadostno za črtarsko grafiko in posnetke zaslona, in nagnjeno k grdim robom, ki jih na pomanjšanih fotografijah prepoznate takoj. rkBicubic poganja razdvojivo jedro Catmull-Rom, rkLanczos3 pa razdvojivo okensko sinc s podporo treh režnjev

Obe razdvojivi jedri tečeta kot dva prehoda, najprej vodoravno nato navpično, s 6 do 12 dotiki na ciljni piksel v čistem Pascalu. To je približno za red velikosti počasneje od poti GDI — natanko zato rkHalftone ostane privzetek. Pri nočnem paketu tisočerih strani je razlika odločitev o razporejanju, ne preferenca. Pri enem samem dokumentu, na katerega čaka uporabnik, je Lanczos3 skoraj zastonj in vidno boljši

Krivulje uteži treh jeder za zmanjševanje slik v HotPDF: rkHalftone se prenese na pot GDI HALFTONE razreda bilinear s podporo ena, rkBicubic poganja razdvojivi kubični Catmull-Rom s podporo dva, rkLanczos3 pa okensko sinc s podporo tri, v zamenjavo približno reda velikosti v hitrosti za vidno boljše fotografije
Tri vrednosti jeder sedejo na resnično različnih točkah krivulje hitrosti in kakovosti: pot GDI razreda bilinear, kubična Catmull-Rom in okensko sinc s tremi režnji, razdvojivi jedri pa normalizirata uteži, tako da nič ne zvoni čez črno ali belo

Dve implementacijski lastnosti sta vredni pozornosti, ker določata, kaj izhod more in česa ne more. Robovi se pripnejo s podvajanjem roba namesto ovijanja ali bledenja, uteži pa so normalizirane na ciljni piksel. Skupaj to pomeni, da rezultat nikoli ne zvoni pod črno ali nad belo, zato klasična Lanczos halacija prekoračitve okoli ostrega roba ne nastopi kot odrezani artefakti v kodirani sliki

var
  Pdf: THotPDF;
  Info: THPDFLoadedResourceOptimizationInfo;
  Changed: Integer;
begin
  Pdf := THotPDF.Create(nil);
  try
    Pdf.LoadFromFile('scanned-contract.pdf');
    Pdf.ImageDownsampleKernel := rkLanczos3;   // nastavite pred klicem
    Changed := Pdf.DownsampleLoadedImages(150, 82, 4096, Info);
    if Changed > 0 then
    begin
      Writeln('resampled images: ', Info.DownsampledImageCount);
      Writeln('kept calibrated : ', Info.PreservedCalibratedImageCount);
      Pdf.SaveToFile('scanned-contract-150dpi.pdf');
    end;
  finally
    Pdf.Free;
  end;
end;

Argument MinimumSavingsBytes, zgoraj 4096, je stražar, ki operacijo drži pošteno. Ponovno kodiranje slike, ki je bila že učinkovito stisnjena, lahko da večji tok kot izvirnik in prevzorčevalnik, ki slepo zamenja vsako sliko, bo občasno povečal datoteko, ki jo je bilo treba skrčiti. Prag pravi: zamenjavo potrdi šele, ko prihrani vsaj toliko bajtov. PreservedCalibratedImageCount sporoča drugo konservativno odločitev — slike, puščene pri miru, ker nosijo umerjen barvni prostor, ki bi ga prevzorčenje ogrozilo

Zakaj je napačen polinomski koeficient tako težko opaziti?

Ker pokvarjeno interpolacijsko jedro ne sesuje in ne javi izjeme, le proizvede sliko, ki izgleda subtilno napačno na način, ki mu nihče ne zna pripisati vzroka. Jedro Catmull-Rom je po delih kubično in njegova zunanja veja v ugnezdjeni obliki Horner je ((-0.5t + 2.5)t - 4)t + 2. Srednji koeficient zapišite kot -5 namesto -4 in funkcija še vedno vrednoti, še vedno vrača števila v verjetnem obsegu in še vedno proizvede sliko

Škoda se pokaže kot W(1), ki ovrednoti na -1, kjer mora biti 0. Negativne uteži se nabirajo, vsota se pri nič odreže in vidni simptom je gradient, kateremu levi konec počrni, ter stopničast rob, ki izgubi svoje vmesne tone. Nič v odpovedi ne kaže na polinom. Preverjanje, ki ga ulovi v sekundah, je aritmetično in ne vizualno: interpolacijsko jedro mora zadostiti W(0) = 1 in W(±1) = W(±2) = 0, vsako jedro, ki zgreši te tri točke, pa ima napako koeficienta — točka. Na te tri vrednosti postavite trditev v enotskem testu in celoten razred tipkarskih napak izgine

Izris zunanje veje kubičnega Catmull-Rom v HotPDF, ki prikazuje, zakaj se napačen koeficient skrije: tipkarska napaka, ki zapiše -5 namesto -4 v ugnezdjeni obliki Horner, še vedno vrednoti in pusti W(1) na -1 ter W(2) na -2, kjer je zahtevana ničla, zato jo trditev W(0) enako 1 plus omejiti dveh ničel ulovi v sekundah
Pokvarjeno jedro nikoli ne sesuje, le vrača števila, ki izgledajo verjetno, zato oko ne ujame tipkarske napake koeficienta. W(0) = 1 z ničlami na plus in minus ena ter dva je trivrstični enotski test

Rastriranje Floyd-Steinberg in kje v cevovodu je doma

Poteza rastriranja je drugačna težava od prevzorčenja in živi na drugem mestu cevovoda. RenderOutputDither uporabi difuzijo napake Floyd-Steinberg po kompoziciji strani, kar je edina umestitev, ki smiselna za monokromski predogled tiskanja ali izvoz v faksu podobni obliki: operacija gre za reduciranje končnega rastra na en bit na piksel, ne za to, kako so bile posamezne slike na vstopu skalirane

Sam algoritem je kratek. Svetilnost se praguje pri 50 odstotkih, kvantizacijska napaka pa se difundira štirim sosedom s klasičnimi utežmi 7/16, 3/16, 5/16 in 1/16 — desno, spodaj-levo, spodaj in spodaj-desno. Izhodni piksel je 0 ali 255 v vsakem kanalu. Nativna alternativa pa vam da trdi prag brez difuzije, ki fotografijo spremeni v silhueto in izgubi vsak srednji ton, ki je nosil vsebino

Umestitev rastriranja Floyd-Steinberg v HotPDF v izrisnem cevovodu: RenderOutputDither teče po kompoziciji strani na končnem 24-bitnem rastru, praguje svetilnost pri 50 odstotkih in difundira vsako kvantizacijsko napako desno in navzdol z utežmi 7/16, 3/16, 5/16 in 1/16 skozi vrstični medpomnilnik, ki mora akumulirati, ter proizvede enobitni monokromski izhod
Rastriranje je doma po kompoziciji, ker končni raster reducira na en bit, in ne zato, kako so bile slike skalirane. Difuzijske uteži se seštejejo v ena, vrstični medpomnilnik pa mora akumulirati in ne prepisovati
// Rastriranje ob izrisu za monokromsko pred ogledno napravo
Pdf.RenderOutputDither := True;

// Isto potezo uporabite tudi na bitni preslikavi, ki jo že imate. Ta mora
// biti pf24bit; funkcija vrne False in ne ugiba
if not HPDFFloydSteinbergDitherBitmap(Preview) then
  raise Exception.Create('dither expects a 24-bit bitmap');

// Neposredni dostop do jedra, ko vzorčite izven dokumentnega cevovoda
Small := HPDFResizeBitmapKernel(Large, 640, 480, rkLanczos3);
try
  Small.SaveToFile('thumb.bmp');
finally
  Small.Free;
end;

Ena implementacijska podrobnost pri difuziji napake ugrizne vsakogar enkrat. Medvrstični napakalni medpomnilnik mora akumulirati. Vsak piksel v naslednji vrstici prejme prispevke treh različnih pikslov v trenutni vrstici — dotikov 3/16, 5/16 in 1/16 —, če koda dodeljuje namesto da bi seštevala, pa vsak zapis zavrže prejšnji prispevek in preživi le zadnji dotik. Slika še vedno izgleda rastrirana, kar jo je težko opaziti, a tekstura je napačna in tonska reprodukcija zdrsi. Test, ki ga ujame, je kvantitativen: rastrirajte enotno srednje sivo polje in zahtevajte, da notranja pokritost pristane med 40 in 60 odstotki

Katero kombinacijo naj uporabi cevovod za zmanjševanje velikosti?

Jedro prilagodite temu, kaj slike dejansko so, rastriranje pa obravnavajte kot zadevo naprave in ne stiskanja. Za fotografske skene, ki morajo preživeti proračun velikosti, rkLanczos3 pri 150 ali 200 DPI obdrži podrobnost, ki je ljudje opazijo, medtem ko število pikslov skrči za faktor štiri ali več. Za posnetke zaslona, diagrame in črtarsko grafiko je rkHalftone resnično v redu in veliko hitrejši, ker te slike imajo malo tonalnih gradientov za ohranitev. Za mešan paket, kjer vsake slike ne morete pregledati, je rkBicubic razumen srednji: boljši od bilinear, približno polovica dotikov Lanczos3

Zmanjševanje je en vzvod med več in ni vedno največji. Dvonivojski skeni se navadno odzovejo veliko bolje na kodirnik, obravnavan v nativnem dvonivojskem stiskanju JBIG2 v Delphi, kjer dobitek pride iz slovarjev simbolov in ne iz štetja pikslov. Preden se odločite, pomaga vedeti, kaj je v datoteki dejansko — zato je tu izvleček slik in njihovih dekodirnih filtrov: inventar objektov slik in njihovega obstoječega stiskanja vam pove, ali prevzorčenje ima kaj pridobiti

Če gradite pred ogledno površino, ki prikaže rezultat, je ista izrisna pot, dokumentirana v izrisu strani PDF v bitno preslikavo, tista, kjer RenderOutputDither učinkuje, tako da rastrirani predogled in rastriran izhod prihajata iz ene kodne poti in ne iz dveh implementacij, ki zdrsita narazen

Široko načelo za obema zmožnostima je, da naj bodo nastavitve kakovosti izrecne in reverzibilne. HotPDF obdrži zgodovinsko vedenje kot privzetek, tako da obstoječa aplikacija nadgradi brez presenetljive spremembe v izhodu ali trajanju, bolje videti in počasnejše poti pa postavi eno dodelitev lastnosti stran. Obe sta del HotPDF Delphi PDF component, ob stroju za optimizacijo virov in izris, na katerem gradijo