Techninis straipsnis

HotPDF vaizdų mažinimo branduoliai ir spausdinimo dithering

HotPDF atskleidžia tris vaizdų mažinimo branduolius per ImageDownsampleKernel savybę ir atskirą Floyd-Steinberg perėjimą per RenderOutputDither. Pirmasis valdo, kaip fotografijos atrodo, jas sumažinus, kad tilptumėte į dydžio biudžetą, antrasis – kaip jos atrodo, puslapį sumažinus iki juodos ir baltos spalvos. Nė vienas pagal nutylėjimą neįjungtas, ir abu pasirenkami dėl tos pačios priežasties: jie kainuoja tikrą laiką

Spaudimas, atvedantis čia žmones, yra pažįstamas. 60 MB nuskaityta sutartis turi išeiti pro el. pašto vartus, kurie atmeta viską, kas viršija 10 MB, arba išrašų partija turi nusileisti fakso stiliaus vienspalviame įrenginyje, kuris kiekvieną pilką pikselį atvaizduoja kaip popierių arba tonerį. Abi problemos yra persamplingo problemos, ir abi turi greitą atsakymą, kuris atrodo blogai, ir lėtą atsakymą, kuris atrodo teisingai

Kuo trys branduoliai iš tikrųjų skiriasi

THPDFResampleKernel turi tris reikšmes, ir jos stovi tikrai skirtinguose greičio ir kokybės kreivės taškuose. rkHalftone perduoda darbą istoriniam GDI StretchBlt keliui su HALFTONE režimu, kuris, nepaisant vardo, yra bilinearinės klasės filtravimas: greitas, pakankamas linijinei grafikai ir ekrano kopijoms, ir linkęs į šiurkščius kraštus, kuriuos sumažintose fotografijose atpažįstate akimirksniu. rkBicubic leidžia atskiriamąjį Catmull-Rom branduolį, o rkLanczos3 – atskiriamąjį langinį sinc su trijų skilčių atrama

Abu atskiriamieji branduoliai veikia dviem perėjimais, horizontaliu ir vertikaliu, su 6 iki 12 atkarpų (taps) kiekvienam paskirties pikseliui gryname Pascal. Tai maždaug eilės tvarka lėčiau nei GDI kelias, ir būtent todėl rkHalftone lieka numatytuoju. Naktinėje tūkstančių puslapių partijoje skirtumas yra planavimo sprendimas, o ne pageidavimas. Viename dokumente, kurio laukia naudotojas, Lanczos3 beveik nieko kainuoja ir aiškiai geriau

Trijų HotPDF mažinimo branduolių svorių kreivės: rkHalftone perduoda bilinearinės klasės GDI HALFTONE keliui su atrama lygia vieną, rkBicubic leidžia atskiriamąjį Catmull-Rom kubinį su atrama lygia du, o rkLanczos3 – langinį sinc su atrama lygia trys, maždaug eilės tvarka aukodami greitį už aiškiai geresnes fotografijas
Trys branduolio reikšmės stovi tikrai skirtinguose greičio ir kokybės kreivės taškuose: bilinearinės klasės GDI kelias, Catmull-Rom kubinis ir trijų skilčių langinis sinc, o atskiriamieji branduoliai normalizuoja svorius, kad niekas neperšoktų už juodos ar baltos

Dvi realizacijos savybės yra vertos žinoti, nes jos lemia, ką išvestis gali ir ko negali. Kraštai suspaudžiami krašto dubliavimu, o ne apvyniojimu ar išblukimu, o svoriai normalizuojami kiekvienam paskirties pikseliui. Kartu šie du faktai reiškia, kad rezultatas niekada neužsisuka žemiau juodos ar aukščiau baltos, tad klasikinė Lanczos pertekimo aureolė aplink aštrų kraštą neatsiranda kaip apkirpti artefaktai užkoduotame vaizde

var
  Pdf: THotPDF;
  Info: THPDFLoadedResourceOptimizationInfo;
  Changed: Integer;
begin
  Pdf := THotPDF.Create(nil);
  try
    Pdf.LoadFromFile('scanned-contract.pdf');
    Pdf.ImageDownsampleKernel := rkLanczos3;   // nustatykite prieš iškvietimą
    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;

MinimumSavingsBytes argumentas, aukščiau 4096, yra sarguoklis, laikantis operaciją sąžiningą. Vaizdo, jau efektyviai suspausto, pakartotinis kodavimas gali duoti ilgesnį srautą nei originalas, o aklai kiekvieną vaizdą keičiantis mažintojas kartais paaugina failą, kurio buvo paprašyta sumažinti. Slenkstis sako: įsipareigokite keitimą tik tada, kai jis sutaupo bent tiek baitų. PreservedCalibratedImageCount praneša kitą konservatyvų sprendimą – nepaliestus vaizdus, nes jie neša kalibruotą spalvų erdvę, kurią persamplingas sugadintų

Kodėl neteisingas polinomo koeficientas toks sunkiai pastebimas?

Nes sugedęs interpoliacijos branduolys nei užstringa, nei meta išimčių, jis tiesiog duoda vaizdą, kuris atrodo subtiliai blogai taip, kad niekas negali to priskirti. Catmull-Rom branduolys yra dalimis kubinis, ir jo išorinė šaka įdėtoje Horner formoje yra ((-0.5t + 2.5)t - 4)t + 2. Parašykite tą vidurinį koeficientą kaip -5 vietoj -4, ir funkcija vis tiek skaičiuojasi, vis tiek grąžina tikėtino diapazono skaičius ir vis tiek duoda vaizdą

Žala pasirodo kaip W(1), skaičiuojantis į -1, kur turi būti 0. Neigiami svoriai kaupiasi, suma nukerpama ties nuliu, ir matomas simptomas yra gradientas, kurio kairysis galas juoduoja, ir pakopinis kraštas, prarandantis tarpines tonines reikšmes. Nieko nesėkmėje nenurodo į polinomą. Patikra, pagavusi tai per sekundes, yra aritmetinė, o ne vaizdinė: interpoliacinis branduolys turi tenkinti W(0) = 1 ir W(±1) = W(±2) = 0, ir bet kuris branduolys, praleidęs tuos tris taškus, turi koeficiento klaidą, taškas. Patikrinkite tuos tris reikšmes vienetiniame teste, ir visa rašybos klaidų defektų klasė dingo

HotPDF bicubic Catmull-Rom išorinės šakos grafikas, rodantis, kodėl neteisingas koeficientas slepiasi: rašybos klaida, parašanti -5 vietoj -4 įdėtoje Horner formoje, vis tiek skaičiuojasi ir palieka W(1) lygų -1 ir W(2) lygų -2 ten, kur reikia nulio, tad W(0) lygybės 1 patikrinimas plus dvi nulinės sąlygos pagavo tai per sekundes
Sugedęs branduolys niekada neužstringa, jis tiesiog grąžina tikėtina atrodančius skaičius, todėl akis negali pagauti koeficiento rašybos klaidos. W(0) = 1 su nuliais ties plius ir minus vienetas ir du yra trijų eilučių vienetinis testas

Floyd-Steinberg dithering ir jo vieta apdorojimo grandinėje

Dither perėjimas yra kitokia problema nei persamplingas ir gyvena kitame konvejerio taške. RenderOutputDither taiko Floyd-Steinberg klaidų difuziją po puslapio kompozicijos, kas yra vienintelė prasminga vieta vienspalvėje spausdinimo peržiūroje ar fakso stiliaus eksporte: operacija yra apie baigto rastrinio vaizdo sumažinimą iki vieno bito pikseliui, o ne apie tai, kaip atskiri vaizdai buvo mastelinti kelyje į vidų

Pats algoritmas trumpas. Šviesis nukerpamas ties 50 procentų, ir kvantavimo klaida difunduojama keturiems kaimynams su klasikiniais 7/16, 3/16, 5/16 ir 1/16 svoriais, einant dešinėn, žemyn kairėn, žemyn ir žemyn dešinėn. Išvesties pikselis yra 0 arba 255 kiekviename kanale. Naivi alternatyva vietoj to, kietas slenkstis be difuzijos, pavertia fotografiją į siluetą ir praranda kiekvieną vidurinį toną, nešusį turinį

HotPDF Floyd-Steinberg dithering vieta atvaizdavimo konvejeryje: RenderOutputDither veikia po puslapio kompozicijos ant baigto 24 bitų rastrinio vaizdo, nukerpdamas šviesį ties 50 procentų ir difunduodamas kiekvieną kvantavimo klaidą dešinėn ir žemyn su 7/16, 3/16, 5/16 ir 1/16 svoriais per eilutės buferį, kuris turi kaupti, duodamas vieno bito vienspalvę išvestį
Dithering vieta – po kompozicijos, nes jis sumažina baigtą rastrinį vaizdą iki vieno bito, o ne dėl to, kaip vaizdai buvo mastelinti. Difuzijos svorių suma lygi vienam, o eilutės buferis turi kaupti, o ne perrašyti
// Atvaizdavimo metu dithering vienspalviam peržiūros įrenginiui
Pdf.RenderOutputDither := True;

// Arba taikykite tą patį perėjimą jūsų jau turimam bitmap. Bitmap turi
// būti pf24bit; funkcija grąžina False, o ne spėja
if not HPDFFloydSteinbergDitherBitmap(Preview) then
  raise Exception.Create('dither expects a 24-bit bitmap');

// Tiesioginė prieiga prie branduolio, kai persamplinate už dokumento konvejero
Small := HPDFResizeBitmapKernel(Large, 640, 480, rkLanczos3);
try
  Small.SaveToFile('thumb.bmp');
finally
  Small.Free;
end;

Klaidų difuzijoje yra viena realizacijos detalė, kuria kiekvienas nustringa po kartą. Eilutės prie eilutės klaidų buferis turi kaupti. Kiekvienas kitos eilutės pikselis gauna įnašus iš trijų skirtingų einamosios eilutės pikselių – 3/16, 5/16 ir 1/16 atkarpų – ir jei kodas priskiria vietoj sudėjimo, kiekvienas rašymas išmeta ankstesnį įnašą, ir išgyvena tik paskutinė atkarpa. Vaizdas vis tiek atrodo ditherintas, kas ir padaro jį sunkiai pastebimą, bet tekstūra yra neteisinga, ir toninė reprodukcija plaukia. Testas, pagavęs tai, yra kiekybinis: ditherinkite vientisą vidutinio pilkumo lauką ir reikalaukite, kad vidinė danga atsitiktų tarp 40 ir 60 procentų

Kurį derinį turėtų rinktis dydžio mažinimo konvejeris?

Suderinkite branduolį su tuo, kuo vaizdai iš tikrųjų yra, ir ditheringą laikykite įrenginio, o ne kompresijos, rūpesčiu. Fotografiniams nuskaitymams, kurie turi išgyventi dydžio biudžetą, rkLanczos3 ties 150 arba 200 DPI išlaiko detalę, kurią žmonės pastebi, nukirsdamas pikselių skaičių keturis ar daugiau kartų. Ekrano kopijoms, diagramoms ir linijinei grafikai rkHalftone tikrai geras ir daug greitesnis, nes tokiuose vaizduose nedaug toninių gradientų išsaugoti. Mišriai partijai, kurioje negalite apžiūrėti kiekvieno vaizdo, rkBicubic yra pagrįstas vidurys: geriau už bilinearinį, maždaug perpus mažiau atkarpų nei Lanczos3

Mažinimas yra viena svertų iš kelių, ir ne visada didžiausia. Dviejų lygių nuskaitymai paprastai gerokai geriau atsako į koduotuvą, aprašytą straipsnyje gimtoji JBIG2 dviejų lygių kompresija Delphi, kur laimė ateina iš simbolių žodynų, o ne pikselių skaičiaus. Prieš apsispręsdami verta žinoti, kas iš tikrųjų yra faile, kam ir tarnauja vaizdų ir jų dekodo filtrų ištraukimas: vaizdo objektų ir jų esamos kompresijos inventorius pasako, ar persamplingas ką turi rinktis

Jei statote peržiūros paviršių, rodantį rezultatą, tas pats atvaizdavimo kelias, dokumentuotas straipsnyje PDF puslapio atvaizdavimas į bitmap, yra vieta, kur veikia RenderOutputDither, tad ditherinta peržiūra ir ditherinta išvestis ateina iš vieno kodo kelio, o ne iš dviejų realizacijų, kurios išsiskiria

Plati abiejų funkcijų principas yra tas, kad kokybės nustatymai turi būti aiškūs ir grąžinami. HotPDF palieka istorinį elgesį kaip numatytąjį, kad esanti programa atsinaujintų be staigaus išvesties ar laiko pasikeitimo, o gražiau atrodančius, lėtesnius kelius pateikia vienos savybės priskyrimo atstumu. Abu yra HotPDF Delphi PDF komponento dalis, kartu su išteklių optimizavimo ir atvaizdavimo technika, kuria jie remiasi