A PDF Library for Delphi az AddModernImageFromFile-on és annak stream- és string-változatain keresztül fogad be AVIF-, HEIF- és JPEG XL-képeket, megőrizve az alfacsatornát, a beágyazott ICC-profilt és a 16 bites csatornákat a PDF-képobjektumba vezető úton. A formátumfelismerés egy korlátozott, mágikus szám alapú olvasással történik, a dekódolás pedig egy cserélhető háttérrendszeren keresztül fut, így semmilyen külső komponens nem hívódik meg egy olyan fájlnál, amely valójában nem tartozik ezen formátumok egyikéhez sem
Ezek a formátumok telefonokon keresztül érkeztek a dokumentum-munkafolyamatokba. Az iOS évek óta alapértelmezetten HEIC-et állít elő, az Android-eszközök AVIF-et, egy sérült alkatrészt fényképező terepi technikus pedig olyan képet küld, amelyet egy 2015-ben épített PDF-jelentéskészítő egyáltalán nem tud megnyitni. Az általános visszaesési útvonal, a platform-bitkép szerinti dekódolás, megbízhatóan 8 bites színt ad, és útközben elveszíti az alfacsatornát és a színprofilt
Mit őriz meg a modern kép útvonal, amit egy bitkép-konverzió elveszít?
Három dolgot, és mindegyiktől függ egy munkafolyamat. Az alfacsatorna megmarad, ami a logóknál és az oldal tartalma fölé komponált termékkivágásoknál számít. Az ICC-profil megmarad, ami mindennél számít, amit nyomtatni vagy színegyeztetni fognak. A 16 bites csatornák pedig megmaradnak, ami az orvosi és tudományos képanyagoknál számít, ahol a 8 bites kvantálás pontosan azokat az árnyalatokat pusztítja el, amelyek miatt a képet felvették
Egy kép platform-bitképen átvezetése egy lépésben mindhármat elveszíti, és mindezt csendben teszi: az eredményül kapott PDF nagyjából jónak tűnik, és senki sem veszi észre, amíg egy nyomda meg nem kérdezi, miért rossz a vállalati vörös. A modern kép hívásokon a 8-as opcióérték az a jelző, amely együtt tartja az alfacsatornát, az ICC-t és a 16 bites csatornákat, és ez az alapértelmezett ezeknél a hívásoknál
Egy kép hozzáadása egy oldalhoz
A hívás egy képazonosítót ad vissza, amelyet ezután kiválasztanak és kirajzolnak, vagy egyetlen lépésben kirajzolnak és felszabadítanak:
uses
PDFlibrary, PDFlibModernImage;
var
Lib: TPDFlib;
ImageID: Integer;
begin
Lib := TPDFlib.Create;
try
Lib.NewDocument;
Lib.SetPageSize('A4');
Lib.NewPage;
// Options = 8 megőrzi az alfacsatornát, az ICC-t és a 16 bites csatornákat
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;
A felismerés megelőzi a dekódolást, és szándékosan szűk. A könyvtár egy korlátozott fejlécet olvas, felismeri az AVIF-et és a HEIF-et azonosító ISO alap médiafájlformátum-márkákat, felismeri a JPEG XL nyers és konténer-aláírásait is, majd visszaállítja a hívó stream-pozícióját. Egy ismeretlen vagy álcázott bemenet soha nem éri el a külső kodeket, ami megakadályozza, hogy egy átnevezett futtatható fájlt egy dekódernek adjunk át, mintha az egy kép lenne
Hol történik valójában a dekódolás?
A modern képformátumok nagy, összetett kodekek, és egyet egy PDF-könyvtárba tenni furcsa tervezési döntés lenne. Az alapértelmezett háttérrendszer dinamikusan tölt be egy telepíthető MagickWand-modult a folyamaton belül, és egy dokumentált sorrendben keresi azt: egy általad beállított explicit fájl vagy könyvtár, környezeti változók, a futtatható fájl könyvtára, majd a rendszer keresési útvonala
Azok az alkalmazások, amelyek már szállítanak egy dekódert, vagy amelyeknek egyáltalán nem szabad külső modult betölteniük, ehelyett saját visszahívást regisztrálnak. A szerződés kicsi: olvasd be a bemeneti streamet, írj egy PNG-t a kimeneti streambe, tartsd tiszteletben a kért tájolást:
function MyDecoder(InStream, OutPNG: TStream;
ImageFormat: TPDFlibModernImageFormat;
ApplyOrientation: Boolean): Boolean;
begin
// Dekódold az InStreamet a saját kodekeddel, és írd a PNG-bájtokat az OutPNG-be
Result := DecodeWithBundledCodec(InStream, OutPNG,
ImageFormat, ApplyOrientation);
end;
begin
RegisterModernImageDecoderBackend(MyDecoder);
// ... add images ...
ClearModernImageDecoderBackend; // vissza az alapértelmezett háttérrendszerhez
end;
A telepítés egy kényelmi funkciót és egy szándékos önmegtartóztatást kap. Ha a kodekkönyvtár tartalmaz egy modules\coders alkönyvtárat, a könyvtár kitölti azokat a kodek környezeti változókat, amelyeket egy ilyen elrendezés igényel, de csak akkor, ha a gazdaalkalmazás még nem állította be azokat. Egy saját futásidejű telepítési stratégiával rendelkező alkalmazás megtartja a sajátját
Miért PNG a közepén?
A hidalás egy memóriabeli PNG-n keresztül, nem egy nyers pixelpufferen, extra lépésnek tűnik, valójában viszont a legolcsóbb helyes megoldás. A PNG mindent kifejez, aminek túl kell élnie: az alfacsatornát, a színtípust, a bitmélységet és egy beágyazott ICC-profilt, a könyvtár pedig már rendelkezik egy érett, jól tesztelt útvonallal a PNG-ből a PDF-képobjektumba, a megfelelő szűrőkkel és színtérrel. Ennek újrafelhasználása azt jelenti, hogy a modern formátumok évekig tartó helyességi munkát örökölnek, ahelyett hogy egy párhuzamos implementációt kapnának
A híd teljes egészében memóriában van, így nem jönnek létre ideiglenes fájlok, és összeomlás esetén nincs szükség takarításra. Egy buktató explicit kezelést igényelt: néhány konverzió elejti az ICC-profilt formátumváltáskor. A háttérrendszer ezért a formátumváltás előtt rögzíti a forrásprofilt, Flate-tel tömöríti, egy érvényes iCCP chunköt épít újraszámolt CRC-vel, és eltávolít minden olyan sRGB chunköt, amely ütközne vele. Tesztelés közben egy dekódolt AVIF megtartotta a 16 bites RGBA-t 16 bites alfával, és az eredményül kapott PDF-ből kinyert profil bájtra pontosan megegyezett a forrásprofillal, 60 960 bájton
Gyakorlati megjegyzések, mielőtt éles környezetben bekapcsolod
Az elérhetőséget induláskor ellenőrizd, ne az első fényképnél. A ModernImageCodecAvailable jelenti, hogy használható-e háttérrendszer, a SetModernImageCodecLibrary pedig egy explicit fájlra vagy könyvtárra mutat, amikor a telepítésed nem szabványos helyre teszi a kodeket:
Lib.SetModernImageCodecLibrary('C:\MyApp\codecs');
if Lib.ModernImageCodecAvailable = 0 then
Log('modern image input unavailable - HEIC and AVIF will be refused');
Figyeld az eredmény fájlméretét. Egy 16 bites RGBA kép beágyazott profillal egy nagy PDF-képobjektum, egy negyvenet tartalmazó jelentés pedig nagy lesz. Amikor a dokumentum képernyős megtekintésre szánt, nem nyomtatásra, a beágyazás előtti lemintavételezés a helyes megoldás, az általános méretcsökkentő eszközöket pedig a PDF-fájlméret optimalizálása ismerteti
Végül dönts tudatosan a színszabályzatról. A forrásprofil megtartása helyes archiválási és nyomdai munkánál; egy dokumentumszintű térre konvertálás akkor helyes, ha egy vegyes fényképkészletnek konzisztensnek kell látszania, a konverziós útvonalat pedig a egy dokumentum átszínezése másik színtérre ismerteti. Ha meg akarod erősíteni, mi került ténylegesen a fájlba, a szöveg-, kép- és betűtípus-kinyerés cikkben szereplő vizsgálati útvonal jelenti a dokumentum által hordozott képobjektumokat
A modern kép-bemenet, a színkezelés és a képoptimalizálás ugyanannak a könyvtárnak a részei Delphihez, C++Builderhez és Free Pascalhoz; a teljes funkciólista a PDF Library for Delphi oldalán található