PDF Library for Delphi prijíma obrázky AVIF, HEIF a JPEG XL ako vstup prostredníctvom AddModernImageFromFile a jej variantov pre stream a reťazec, pričom na ceste do objektu obrázka PDF zachováva alfa kanál, vložený profil ICC a 16-bitové kanály. Detekcia formátu prebieha na ohraničenom čítaní magického čísla a dekódovanie beží cez vymeniteľný backend, takže pri súbore, ktorý v skutočnosti nie je žiadnym z týchto formátov, sa nevolá nič externé
Tieto formáty sa do pracovných postupov s dokumentmi dostali cez telefóny. iOS už roky predvolene produkuje HEIC, zariadenia Android produkujú AVIF, a terénny technik fotografiaci poškodenú súčiastku odošle obrázok, ktorý generátor PDF reportov postavený v roku 2015 vôbec nedokáže otvoriť. Generická náhradná cesta, dekódovanie cez platformovú bitmapu, spoľahlivo produkuje 8-bitovú farbu a po ceste stráca alfa kanál aj farebný profil
Čo zachováva moderná cesta obrázkov, čo konverzia cez bitmapu stráca?
Tri veci, a každá má pracovný postup, ktorý na nej závisí. Prežíva alfa kanál, čo je dôležité pri logách a výrezoch produktov skladaných nad obsahom stránky. Prežíva profil ICC, čo je dôležité pri čomkoľvek, čo sa bude tlačiť alebo farebne zhodovať. A prežívajú 16-bitové kanály, čo je dôležité pri medicínskej a vedeckej obrazovej dokumentácii, kde 8-bitová kvantizácia ničí presne tie odtiene, kvôli ktorým bol obrázok zachytený
Prevedenie obrázka cez platformovú bitmapu stratí všetky tri v jednom kroku, a robí to ticho: výsledné PDF vyzerá približne správne a nikto si to nevšimne, kým sa tlačiareň nespýta, prečo je firemná červená nesprávna. Hodnota možnosti 8 pri volaniach moderných obrázkov je príznak, ktorý drží pohromade alfa kanál, ICC aj 16-bitové kanály, a je pri týchto volaniach predvolený
Pridanie obrázka na stránku
Volanie vráti identifikátor obrázka, ktorý sa potom vyberie a nakreslí, alebo nakreslí a uvoľní v jednom kroku:
uses
PDFlibrary, PDFlibModernImage;
var
Lib: TPDFlib;
ImageID: Integer;
begin
Lib := TPDFlib.Create;
try
Lib.NewDocument;
Lib.SetPageSize('A4');
Lib.NewPage;
// Options = 8 zachováva alfa kanál, ICC a 16-bitové kanály
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;
Detekcia predchádza dekódovaniu a je zámerne úzka. Knižnica prečíta ohraničenú hlavičku, rozpozná značky formátu ISO base media file, ktoré identifikujú AVIF a HEIF, a rozpozná surové aj kontajnerové signatúry JPEG XL, potom obnoví pozíciu streamu volajúceho. Neznámy alebo zamaskovaný vstup sa nikdy nedostane k externému kodeku, čím sa zabráni tomu, aby sa premenovaný spustiteľný súbor odovzdal dekodéru, akoby to bol obrázok
Kde sa dekódovanie v skutočnosti odohráva?
Moderné obrázkové formáty sú veľké, zložité kodeky, a vložiť jeden z nich priamo do PDF knižnice by bolo zvláštne dizajnové rozhodnutie. Predvolený backend dynamicky načíta nasaditeľný modul MagickWand v rámci procesu a hľadá ho v zdokumentovanom poradí: explicitný súbor alebo adresár, ktorý nastavíte, premenné prostredia, adresár spustiteľného súboru a systémovú cestu vyhľadávania
Aplikácie, ktoré už dodávajú vlastný dekodér, alebo ktoré nesmú načítať žiadny externý modul, si namiesto toho zaregistrujú vlastný callback. Zmluva je malá: prečítať vstupný stream, zapísať PNG do výstupného streamu, rešpektovať požadovanú orientáciu:
function MyDecoder(InStream, OutPNG: TStream;
ImageFormat: TPDFlibModernImageFormat;
ApplyOrientation: Boolean): Boolean;
begin
// Dekódujte InStream vlastným kodekom a zapíšte bajty PNG do OutPNG
Result := DecodeWithBundledCodec(InStream, OutPNG,
ImageFormat, ApplyOrientation);
end;
begin
RegisterModernImageDecoderBackend(MyDecoder);
// ... pridajte obrázky ...
ClearModernImageDecoderBackend; // späť na predvolený backend
end;
Nasadenie získa jedno pohodlie a jedno zámerné zdržanie sa. Ak adresár kodeku obsahuje podadresár modules\coders, knižnica vyplní premenné prostredia kodeku, ktoré takéto usporiadanie potrebuje, no iba vtedy, keď ich hostiteľská aplikácia ešte nenastavila. Aplikácia s vlastnou stratégiou nasadenia za behu si svoju stratégiu ponechá
Prečo PNG v strede?
Premostenie cez PNG v pamäti namiesto surového bufferu pixelov vyzerá ako navyše krok a v skutočnosti je najlacnejším správnym krokom. PNG vyjadruje všetko, čo musí prežiť — alfa kanál, typ farby, bitovú hĺbku a vložený profil ICC —, a knižnica už má vyzretú, dôkladne otestovanú cestu z PNG do objektu obrázka PDF so správnymi filtrami a farebným priestorom. Jej opätovné použitie znamená, že moderné formáty dedia roky práce na správnosti namiesto toho, aby dostali paralelnú implementáciu
Premostenie je úplne v pamäti, takže sa nevytvárajú žiadne dočasné súbory a pri páde nie je potrebné žiadne čistenie. Jedna vráska si vyžiadala explicitné ošetrenie: niektoré konverzie pri zmene formátu zahodia profil ICC. Backend preto zachytí zdrojový profil pred prepnutím formátu, skomprimuje ho pomocou Flate, zostaví platný blok iCCP s prepočítaným CRC a odstráni akýkoľvek blok sRGB, ktorý by s ním kolidoval. Pri testovaní si dekódovaný AVIF zachoval 16-bitové RGBA so 16-bitovou alfou a profil extrahovaný z výsledného PDF sa zhodoval so zdrojovým profilom bajt po bajte pri 60 960 bajtoch
Praktické poznámky pred nasadením do produkcie
Overte dostupnosť pri štarte, nie pri prvej fotografii. ModernImageCodecAvailable hlási, či sa dá backend použiť, a SetModernImageCodecLibrary ukáže na explicitný súbor alebo adresár, keď vaše nasadenie umiestňuje kodek na neštandardné miesto:
Lib.SetModernImageCodecLibrary('C:\MyApp\codecs');
if Lib.ModernImageCodecAvailable = 0 then
Log('modern image input unavailable - HEIC and AVIF will be refused');
Sledujte veľkosť výsledného súboru. 16-bitový obrázok RGBA s vloženým profilom je veľký objekt obrázka PDF a report so štyridsiatimi takýmito obrázkami bude veľký. Keď je dokument určený na zobrazenie na obrazovke, nie na tlač, downsampling pred vložením je správny kompromis, a všeobecné páky na veľkosť opisuje časť optimalizácia veľkosti súboru PDF
Napokon zámerne rozhodnite o farebnej politike. Zachovanie zdrojového profilu je správne pre archívnu prácu a tlač; konverzia do priestoru platného pre celý dokument je správna, keď zmiešaná sada fotografií musí vyzerať konzistentne, a cestu konverzie opisuje časť prefarbenie dokumentu do iného farebného priestoru. Ak potrebujete potvrdiť, čo sa v skutočnosti dostalo do súboru, cesta inšpekcie v časti extrakcia textu, obrázkov a písiem hlási, aké objekty obrázkov dokument nesie
Vstup moderných obrázkov, správa farieb a optimalizácia obrázkov sú súčasťou tej istej knižnice pre Delphi, C++Builder a Free Pascal; kompletný zoznam funkcií nájdete na stránke PDF Library for Delphi