Tehnični članak

Vdelava slik AVIF, HEIF in JPEG XL v PDF iz Delphija

PDF Library for Delphi prek AddModernImageFromFile in njenih različic za tok in niz sprejme slike AVIF, HEIF in JPEG XL kot vhod, pri čemer na poti v objekt slike PDF ohrani alfo, vdelan profil ICC in 16-bitne kanale. Zaznavanje oblike poteka na omejenem branju magičnega števila, dekodiranje pa teče prek zamenljivega zaledja, tako da za datoteko, ki dejansko ni ena od teh oblik, ni poklican noben zunanji program

Te oblike so v poteke dela z dokumenti prišle prek telefonov. iOS že leta privzeto ustvarja HEIC, naprave Android ustvarjajo AVIF, terenski tehnik, ki fotografira poškodovan del, pa pošlje sliko, ki je generator poročil PDF, zgrajen leta 2015, sploh ne more odpreti. Splošna rezervna pot, dekodiranje prek platformske bitne slike, zanesljivo da 8-bitno barvo in po poti izgubi alfo in barvni profil

Kaj sodobna slikovna pot ohrani, kar pretvorba v bitno sliko izgubi?

Tri stvari, vsaka pa ima potek dela, ki je odvisen od nje. Alfa preživi, kar je pomembno za logotipe in izrezke izdelkov, sestavljene nad vsebino strani. Profil ICC preživi, kar je pomembno za vse, kar bo natisnjeno ali barvno usklajeno. In 16-bitni kanali preživijo, kar je pomembno za medicinske in znanstvene slike, kjer 8-bitna kvantizacija uniči prav tiste odtenke, zaradi katerih je bila slika sploh zajeta

Speljati sliko skozi platformsko bitno sliko v enem koraku izgubi vse tri, in to stori tiho: nastali PDF je videti približno pravilen, nihče pa tega ne opazi, dokler tiskarna ne vpraša, zakaj je korporacijska rdeča napačna. Vrednost možnosti 8 pri klicih za sodobne slike je zastavica, ki skupaj ohrani alfo, ICC in 16-bitne kanale, in je privzeta za te klice

Dodajanje ene na stran

Klic vrne identifikator slike, ki je nato izbran in narisan, ali pa v enem koraku narisan in sproščen:

uses
  PDFlibrary, PDFlibModernImage;

var
  Lib: TPDFlib;
  ImageID: Integer;
begin
  Lib := TPDFlib.Create;
  try
    Lib.NewDocument;
    Lib.SetPageSize('A4');
    Lib.NewPage;

    // Options = 8 ohrani alfo, ICC in 16-bitne kanale
    ImageID := Lib.AddModernImageFromFile('site-photo.heic', 8);
    if ImageID > 0 then
      Lib.DrawImageAndRelease(ImageID, 40, 40, 515, 340)
    else
      Lib.DrawText(40, 40, 'image could not be decoded');

    Lib.SaveToFile('inspection-report.pdf');
  finally
    Lib.Free;
  end;
end;

Zaznavanje je pred dekodiranjem in je namerno ozko. Knjižnica prebere omejeno glavo, prepozna oznake oblike ISO base media file, ki identificirajo AVIF in HEIF, ter prepozna tako surove kot vsebniške podpise JPEG XL, nato pa obnovi položaj klicateljevega toka. Neznan ali prikrit vhod nikoli ne doseže zunanjega kodeka, kar prepreči, da bi preimenovana izvedljiva datoteka dekodirniku bila predana, kot da je slika

Kje se dekodiranje dejansko zgodi?

Sodobne slikovne oblike so veliki, zapleteni kodeki, njihova vgraditev v knjižnico PDF pa bi bila čudna oblikovna izbira. Privzeto zaledje dinamično naloži razmestljiv modul MagickWand znotraj procesa in ga išče v dokumentiranem vrstnem redu: izrecno datoteko ali imenik, ki ga nastavite, spremenljivke okolja, imenik izvedljive datoteke in sistemsko iskalno pot

Aplikacije, ki že dobavljajo dekodirnik ali sploh ne smejo naložiti zunanjega modula, namesto tega registrirajo svoj lasten povratni klic. Pogodba je majhna: preberi vhodni tok, zapiši PNG v izhodni tok, upoštevaj zahtevano usmerjenost:

function MyDecoder(InStream, OutPNG: TStream;
  ImageFormat: TPDFlibModernImageFormat;
  ApplyOrientation: Boolean): Boolean;
begin
  // Dekodirajte InStream s svojim lastnim kodekom in zapišite bajte PNG v OutPNG
  Result := DecodeWithBundledCodec(InStream, OutPNG,
    ImageFormat, ApplyOrientation);
end;

begin
  RegisterModernImageDecoderBackend(MyDecoder);
  // ... dodajte slike ...
  ClearModernImageDecoderBackend;    // nazaj na privzeto zaledje
end;

Razmestitev dobi eno udobje in eno namerno zadržanost. Če imenik kodeka vsebuje podimenik modules\coders, knjižnica zapolni spremenljivke okolja kodeka, ki jih taka postavitev potrebuje, vendar samo, kadar jih gostiteljska aplikacija še ni nastavila. Aplikacija z lastno strategijo razmestitve ob teku obdrži svojo

Zakaj PNG na sredini?

Premoščanje prek PNG v pomnilniku namesto surovega medpomnilnika slikovnih pik je videti kot dodaten korak, v resnici pa je najcenejši pravilen. PNG izrazi vse, kar mora preživeti — alfo, vrsto barve, bitno globino in vdelan profil ICC — knjižnica pa že ima zrelo, dobro preizkušeno pot iz PNG v objekt slike PDF s pravimi filtri in barvnim prostorom. Njena ponovna uporaba pomeni, da sodobne oblike podedujejo leta dela na pravilnosti, namesto da bi dobile vzporedno implementacijo

Most je v celoti v pomnilniku, zato se ne ustvarjajo začasne datoteke in ob zrušitvi ni potrebno čiščenje. Ena podrobnost je zahtevala izrecno obravnavo: nekatere pretvorbe ob spremembi oblike izgubijo profil ICC. Zaledje zato zajame izvorni profil pred zamenjavo oblike, ga stisne s Flate, zgradi veljaven kos iCCP s ponovno izračunanim CRC in odstrani vsak kos sRGB, ki bi bil z njim v sporu. V testiranju je dekodiran AVIF ohranil 16-bitni RGBA s 16-bitno alfo, profil, izvlečen iz nastalega PDF, pa se je z izvornim profilom ujemal bajt za bajtom pri 60.960 bajtih

Praktične opombe, preden to omogočite v produkciji

Razpoložljivost preverite ob zagonu in ne šele ob prvi fotografiji. ModernImageCodecAvailable javi, ali je zaledje mogoče uporabiti, SetModernImageCodecLibrary pa pokaže na izrecno datoteko ali imenik, kadar vaša razmestitev postavi kodek nekam nestandardno:

Lib.SetModernImageCodecLibrary('C:\MyApp\codecs');
if Lib.ModernImageCodecAvailable = 0 then
  Log('modern image input unavailable - HEIC and AVIF will be refused');

Pazite na velikost datoteke rezultata. 16-bitna slika RGBA z vdelanim profilom je velik objekt slike PDF, poročilo s štiridesetimi takimi pa bo veliko. Kadar je dokument namenjen ogledu na zaslonu in ne tisku, je zmanjšanje ločljivosti pred vdelavo pravilna izbira, splošni vzvodi velikosti pa so opisani v optimizaciji velikosti datoteke PDF

Nazadnje namensko odločite o barvni politiki. Ohranitev izvornega profila je pravilna za arhivsko in tiskovno delo; pretvorba v prostor za cel dokument je pravilna, kadar mora mešan nabor fotografij izgledati skladno, pot pretvorbe pa je opisana v prebarvanju dokumenta v drug barvni prostor. Če morate potrditi, kaj je dejansko pristalo v datoteki, pot pregleda v izvlečenju besedila, slik in pisav javi slikovne objekte, ki jih dokument nosi

Sodoben vhod slik, upravljanje barv in optimizacija slik so del iste knjižnice za Delphi, C++Builder in Free Pascal; celoten seznam funkcij je na strani PDF Library for Delphi