PDF Library for Delphi acceptă imagini AVIF, HEIF și JPEG XL ca intrare prin AddModernImageFromFile și variantele ei de flux și șir, păstrând canalul alfa, profilul ICC încorporat și canalele pe 16 biți pe drumul spre obiectul de imagine PDF. Detectarea formatului se întâmplă pe o citire mărginită a numărului magic, iar decodarea rulează printr-un backend înlocuibil, așa că nimic extern nu este invocat pentru un fișier care nu este de fapt unul dintre acele formate
Aceste formate au ajuns în fluxurile de lucru cu documente prin telefoane. iOS produce HEIC implicit de ani de zile, dispozitivele Android produc AVIF, iar un tehnician de teren care fotografiază o piesă deteriorată trimite o imagine pe care un generator de rapoarte PDF construit în 2015 nu o poate deschide deloc. Calea de rezervă generică, decodarea printr-un bitmap de platformă, produce în mod fiabil culoare pe 8 biți și pierde pe parcurs canalul alfa și profilul de culoare
Ce păstrează calea de imagine modernă pe care o conversie bitmap o pierde?
Trei lucruri, iar fiecare are un flux de lucru care depinde de el. Canalul alfa supraviețuiește, ceea ce contează pentru logo-uri și decupaje de produs compuse peste conținutul paginii. Profilul ICC supraviețuiește, ceea ce contează pentru orice va fi tipărit sau potrivit de culoare. Iar canalele pe 16 biți supraviețuiesc, ceea ce contează pentru imagini medicale și științifice unde cuantizarea pe 8 biți distruge exact gradațiile pentru care imaginea a fost capturată
Trecerea unei imagini printr-un bitmap de platformă pierde toate cele trei într-un singur pas, și o face în tăcere: PDF-ul rezultat arată aproximativ corect, iar nimeni nu observă până când o imprimantă nu întreabă de ce roșul corporativ e greșit. Valoarea de opțiune 8 pe apelurile de imagine moderne este indicatorul care păstrează alfa, ICC și canalele pe 16 biți împreună, și este implicită pentru acele apeluri
Adăugarea uneia pe o pagină
Apelul returnează un identificator de imagine, care este apoi selectat și desenat, sau desenat și eliberat într-un singur pas:
uses
PDFlibrary, PDFlibModernImage;
var
Lib: TPDFlib;
ImageID: Integer;
begin
Lib := TPDFlib.Create;
try
Lib.NewDocument;
Lib.SetPageSize('A4');
Lib.NewPage;
// Options = 8 păstrează alfa, ICC și canalele pe 16 biți
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;
Detectarea precede decodarea și este deliberat îngustă. Biblioteca citește un antet mărginit, recunoaște mărcile de format de fișier media de bază ISO care identifică AVIF și HEIF și recunoaște atât semnăturile brute, cât și cele de container ale JPEG XL, apoi restaurează poziția de flux a apelantului. O intrare necunoscută sau deghizată nu ajunge niciodată la codecul extern, ceea ce împiedică un executabil redenumit să fie predat unui decodor ca și cum ar fi o imagine
Unde se întâmplă efectiv decodarea?
Formatele de imagine moderne sunt codecuri mari și complexe, iar a pune unul într-o bibliotecă PDF ar fi o alegere de design ciudată. Backend-ul implicit încarcă dinamic, în proces, un modul MagickWand implementabil și îl caută într-o ordine documentată: un fișier sau director explicit pe care îl setezi, variabile de mediu, directorul executabilului și calea de căutare a sistemului
Aplicațiile care livrează deja un decodor, sau care nu trebuie să încarce deloc un modul extern, își înregistrează propriul callback în schimb. Contractul este mic: citește fluxul de intrare, scrie un PNG în fluxul de ieșire, respectă orientarea cerută:
function MyDecoder(InStream, OutPNG: TStream;
ImageFormat: TPDFlibModernImageFormat;
ApplyOrientation: Boolean): Boolean;
begin
// Decodează InStream cu propriul tău codec și scrie octeții PNG în OutPNG
Result := DecodeWithBundledCodec(InStream, OutPNG,
ImageFormat, ApplyOrientation);
end;
begin
RegisterModernImageDecoderBackend(MyDecoder);
// ... adaugă imagini ...
ClearModernImageDecoderBackend; // înapoi la backend-ul implicit
end;
Implementarea primește o comoditate și o reținere deliberată. Dacă directorul de codec conține un subdirector modules\coders, biblioteca completează variabilele de mediu de codec de care are nevoie un astfel de aranjament, dar doar când aplicația gazdă nu le-a setat deja. O aplicație cu propria strategie de implementare a runtime-ului o păstrează pe a ei
De ce PNG la mijloc?
Trecerea printr-un PNG în memorie, în loc de un buffer de pixeli brut, pare un pas suplimentar și este de fapt cel mai ieftin corect. PNG exprimă tot ce trebuie să supraviețuiască, alfa, tip de culoare, adâncime de biți și un profil ICC încorporat, iar biblioteca are deja o cale matură, bine testată, de la PNG la un obiect de imagine PDF cu filtrele și spațiul de culoare corecte. Reutilizarea ei înseamnă că formatele moderne moștenesc ani de muncă de corectitudine, în loc să primească o implementare paralelă
Puntea este în întregime în memorie, așa că nu se creează fișiere temporare și nu e nevoie de curățare la un crash. O particularitate a necesitat gestionare explicită: unele conversii elimină profilul ICC la schimbarea formatului. Backend-ul așadar capturează profilul sursă înainte de schimbarea formatului, îl comprimă cu Flate, construiește un chunk iCCP valid cu un CRC recalculat, și elimină orice chunk sRGB care ar intra în conflict cu el. În testare, un AVIF decodat a păstrat RGBA pe 16 biți cu alfa pe 16 biți, iar profilul extras din PDF-ul rezultat s-a potrivit cu profilul sursă octet cu octet, la 60.960 de octeți
Note practice înainte de a activa în producție
Verifică disponibilitatea la pornire, nu la prima fotografie. ModernImageCodecAvailable raportează dacă un backend poate fi folosit, iar SetModernImageCodecLibrary indică un fișier sau director explicit când implementarea ta pune codecul într-un loc neobișnuit:
Lib.SetModernImageCodecLibrary('C:\MyApp\codecs');
if Lib.ModernImageCodecAvailable = 0 then
Log('modern image input unavailable - HEIC and AVIF will be refused');
Urmărește dimensiunea fișierului rezultat. O imagine RGBA pe 16 biți cu un profil încorporat este un obiect de imagine PDF mare, iar un raport cu patruzeci dintre ele va fi mare. Când documentul este destinat vizualizării pe ecran, nu tiparului, subeșantionarea înainte de încorporare este alegerea corectă, iar pârghiile generale de dimensiune sunt acoperite în optimizarea dimensiunii fișierului PDF
În final, decide politica de culoare deliberat. Păstrarea profilului sursă este corectă pentru lucrări de arhivare și tipar; convertirea la un spațiu la nivel de document este corectă când un set mixt de fotografii trebuie să arate coerent, iar ruta de conversie este descrisă în recolorarea unui document într-un alt spațiu de culoare. Dacă trebuie să confirmi ce a ajuns efectiv în fișier, calea de inspecție din extragerea de text, imagini și fonturi raportează obiectele de imagine pe care le poartă un document
Intrarea de imagine modernă, gestionarea culorii și optimizarea imaginii fac parte din aceeași bibliotecă pentru Delphi, C++Builder și Free Pascal; lista completă de funcții este pe pagina PDF Library for Delphi