PDF Library for Delphi accepteert AVIF-, HEIF- en JPEG XL-afbeeldingen als invoer via AddModernImageFromFile en de stream- en stringvarianten daarvan, met behoud van alfa, het ingesloten ICC-profiel en 16-bits kanalen op weg naar het PDF-afbeeldingsobject. Formaatdetectie gebeurt via een begrensde magic-number-lezing, en decodering verloopt via een vervangbare backend, zodat niets externs wordt aangeroepen voor een bestand dat niet daadwerkelijk een van die formaten is
Deze formaten zijn documentworkflows binnengekomen via telefoons. iOS produceert al jaren standaard HEIC, Android-toestellen produceren AVIF, en een veldtechnicus die een beschadigd onderdeel fotografeert, stuurt een afbeelding die een PDF-rapportgenerator uit 2015 helemaal niet kan openen. Het generieke fallbackpad, decoderen via een platformbitmap, levert betrouwbaar 8-bits kleur op en verliest onderweg alfa en het kleurprofiel
Wat behoudt het moderne-afbeeldingspad dat een bitmapconversie verliest?
Drie dingen, en elk daarvan heeft een workflow die ervan afhankelijk is. Alfa blijft behouden, wat ertoe doet voor logo's en productuitsnedes die over pagina-inhoud worden gecomponeerd. Het ICC-profiel blijft behouden, wat ertoe doet voor alles wat wordt afgedrukt of kleurgematcht. En 16-bits kanalen blijven behouden, wat ertoe doet voor medische en wetenschappelijke beeldvorming waar 8-bits kwantisering precies de gradaties vernietigt waarvoor de afbeelding is vastgelegd
Een afbeelding door een platformbitmap laten gaan, verliest alle drie in één stap, en dat gebeurt stilzwijgend: de resulterende PDF ziet er ongeveer goed uit, en niemand merkt het totdat een drukker vraagt waarom het bedrijfsrood niet klopt. Optiewaarde 8 op de moderne-afbeeldingsaanroepen is de vlag die alfa, ICC en 16-bits kanalen samen behoudt, en het is de standaard voor die aanroepen
Er een aan een pagina toevoegen
De aanroep retourneert een afbeeldings-ID, die vervolgens wordt geselecteerd en getekend, of in één stap getekend en vrijgegeven:
uses
PDFlibrary, PDFlibModernImage;
var
Lib: TPDFlib;
ImageID: Integer;
begin
Lib := TPDFlib.Create;
try
Lib.NewDocument;
Lib.SetPageSize('A4');
Lib.NewPage;
// Options = 8 behoudt alfa, ICC en 16-bits kanalen
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;
Detectie gaat aan decodering vooraf en is bewust smal. De bibliotheek leest een begrensde header, herkent de ISO-basismediabestandsformaat-merken die AVIF en HEIF identificeren, en herkent zowel de ruwe als de containersignaturen van JPEG XL, en herstelt vervolgens de streampositie van de aanroeper. Een onbekende of vermomde invoer bereikt de externe codec nooit, wat voorkomt dat een hernoemd uitvoerbaar bestand aan een decoder wordt gegeven alsof het een afbeelding was
Waar vindt de decodering eigenlijk plaats?
Moderne afbeeldingsformaten zijn grote, complexe codecs, en er een in een PDF-bibliotheek stoppen zou een vreemde ontwerpkeuze zijn. De standaardbackend laadt dynamisch een implementeerbare MagickWand-module in-process en zoekt deze in een gedocumenteerde volgorde: een expliciet bestand of directory die u instelt, omgevingsvariabelen, de directory van het uitvoerbare bestand, en het systeemzoekpad
Toepassingen die al een decoder meeleveren, of die helemaal geen externe module mogen laden, registreren in plaats daarvan hun eigen callback. Het contract is klein: lees de invoerstream, schrijf een PNG naar de uitvoerstream, respecteer de gevraagde oriëntatie:
function MyDecoder(InStream, OutPNG: TStream;
ImageFormat: TPDFlibModernImageFormat;
ApplyOrientation: Boolean): Boolean;
begin
// Decodeer InStream met uw eigen codec en schrijf PNG-bytes naar OutPNG
Result := DecodeWithBundledCodec(InStream, OutPNG,
ImageFormat, ApplyOrientation);
end;
begin
RegisterModernImageDecoderBackend(MyDecoder);
// ... afbeeldingen toevoegen ...
ClearModernImageDecoderBackend; // terug naar de standaardbackend
end;
Deployment krijgt één gemak en één bewuste terughoudendheid. Als de codecdirectory een submap modules\coders bevat, vult de bibliotheek de codec-omgevingsvariabelen in die zo'n indeling nodig heeft, maar alleen wanneer de hosttoepassing die nog niet heeft ingesteld. Een toepassing met haar eigen runtime-deploymentstrategie behoudt die
Waarom PNG in het midden?
Overbruggen via een PNG in het geheugen in plaats van een ruwe pixelbuffer lijkt een extra stap en is eigenlijk de goedkoopste correcte optie. PNG drukt alles uit wat moet overleven: alfa, kleurtype, bitdiepte en een ingesloten ICC-profiel, en de bibliotheek heeft al een volwassen, goed geteste route van PNG naar een PDF-afbeeldingsobject met de juiste filters en kleurruimte. Die hergebruiken betekent dat moderne formaten jaren aan correctheidswerk erven in plaats van een parallelle implementatie te krijgen
De brug bevindt zich volledig in het geheugen, dus er worden geen tijdelijke bestanden aangemaakt en is geen opruiming nodig bij een crash. Eén complicatie vereiste expliciete afhandeling: sommige conversies laten het ICC-profiel vallen bij het wisselen van formaat. De backend legt daarom het bronprofiel vast vóór de formaatwisseling, comprimeert het met Flate, bouwt een geldig iCCP-chunk met een herberekende CRC, en verwijdert elk sRGB-chunk dat ermee zou botsen. Bij testen behield een gedecodeerde AVIF 16-bits RGBA met 16-bits alfa, en het profiel geëxtraheerd uit de resulterende PDF kwam byte voor byte overeen met het bronprofiel, bij 60.960 bytes
Praktische opmerkingen voordat u dit in productie inschakelt
Controleer beschikbaarheid bij het opstarten in plaats van bij de eerste foto. ModernImageCodecAvailable rapporteert of een backend kan worden gebruikt, en SetModernImageCodecLibrary wijst naar een expliciet bestand of directory wanneer uw deployment de codec ergens niet-standaard plaatst:
Lib.SetModernImageCodecLibrary('C:\MyApp\codecs');
if Lib.ModernImageCodecAvailable = 0 then
Log('modern image input unavailable - HEIC and AVIF will be refused');
Houd de bestandsgrootte van het resultaat in de gaten. Een 16-bits RGBA-afbeelding met een ingesloten profiel is een groot PDF-afbeeldingsobject, en een rapport met veertig ervan wordt groot. Wanneer het document bestemd is voor schermweergave in plaats van afdrukken, is downsampling vóór het insluiten de juiste afweging, en de algemene groottehendels worden behandeld in PDF-bestandsgrootte-optimalisatie
Bepaal ten slotte bewust het kleurbeleid. Het bronprofiel behouden is correct voor archief- en drukwerk; converteren naar een documentbrede ruimte is correct wanneer een gemengde set foto's er consistent moet uitzien, en de conversieroute wordt beschreven in een document herkleuren naar een andere kleurruimte. Als u moet bevestigen wat daadwerkelijk in het bestand terechtkwam, rapporteert het inspectiepad in tekst-, afbeeldings- en lettertype-extractie de afbeeldingsobjecten die een document draagt
Moderne-afbeeldingsinvoer, kleurbeheer en afbeeldingsoptimalisatie maken deel uit van dezelfde bibliotheek voor Delphi, C++Builder en Free Pascal; de volledige functielijst staat op de PDF Library for Delphi-pagina