Delphi biedt geen eigen manieren om een vector-PDF te converteren naar een rasterafbeelding die kan worden opgeslagen of via een netwerk kan worden verzonden. U heeft een renderengine nodig. De PDFium Component omhult de PDFium-engine en verzorgt de GDI/GDI+-integratie, waardoor de conversie van PDF-pagina's naar JPEG slechts een kwestie wordt van wiskunde voor het schalen, een render-aanroep op VCL TBitmap, en codering via de standaard TJPEGImage
De PDF openen en pagina-afmetingen verkrijgen
Het proces start via TPdf, niet via de grafische component (TPdfView). Wijs de FileName toe en stel Active in op True. Onthoud dat Active := True geen uitzondering opwerpt bij een mislukte actie; u moet controleren of de toewijzing daadwerkelijk standhoudt. Daarna is the PageNumber (1-gebaseerd) gereed voor gebruik
var
Pdf: TPdf;
begin
Pdf := TPdf.Create(nil);
try
Pdf.FileName := 'document.pdf';
Pdf.Active := True;
if not Pdf.Active then
Exit; // File not found or password protected
Pdf.PageNumber := 1;
// ...
finally
Pdf.Free;
end;
end;
In PDF's worden pagina-afmetingen uitgedrukt in punten, waarbij 1 punt in theorie 1/72 inch is. Zodra PageNumber is toegewezen, geven Pdf.PageWidth en Pdf.PageHeight de afmetingen in punten terug, zoals gespecificeerd in de MediaBox of CropBox van het document
De afmetingen van de afbeeldingsuitvoer berekenen
Om te renderen, heeft u een resolutie in DPI (dots per inch) nodig, wat bepaalt hoe gedetailleerd en groot uw resulterende afbeelding wordt. Een DPI van 72 resulteert in één pixel voor elk PDF-punt (snelle export met lage resolutie), terwijl een DPI van 300 documenten produceert die geschikt zijn voor OCR of weergave met hoge resolutie
var
DPI: Integer;
BmpWidth, BmpHeight: Integer;
begin
DPI := 300; // Standard print quality
// PDF dimensions are in 1/72 inch points.
// Multiply by (DPI / 72.0) to get target pixel dimensions.
BmpWidth := Round(Pdf.PageWidth * (DPI / 72.0));
BmpHeight := Round(Pdf.PageHeight * (DPI / 72.0));
// ...
end;
Een standaard 8,5 x 11 inch pagina bij 300 DPI vereist een afbeelding van 2550 x 3300 pixels, wat behoorlijk wat geheugen vergt bij de toewijzing als 32-bits DIB (apparaat-onafhankelijke bitmap). Ga er niet vanuit dat het geheugen altijd toereikend is bij het verwerken van documenten met extra grote formaten (bijv. architectonische ontwerpen)
De render uitvoeren naar een TBitmap
Voorafgaand aan de conversie naar JPEG, moet de pixelinhoud worden gerenderd in een VCL TBitmap met behulp van de ingebouwde DrawPage-methode. Met deze methode kan de PDFium-bibliotheek direct in de device context (DC) van het canvas tekenen
var
Bmp: TBitmap;
begin
Bmp := TBitmap.Create;
try
// Use pf32bit to avoid complex palette issues when rendering via GDI/GDI+
Bmp.PixelFormat := pf32bit;
Bmp.Width := BmpWidth;
Bmp.Height := BmpHeight;
// Fill background with white because PDF background is technically transparent
Bmp.Canvas.Brush.Color := clWhite;
Bmp.Canvas.Brush.Style := bsSolid;
Bmp.Canvas.FillRect(Rect(0, 0, BmpWidth, BmpHeight));
// Render the page contents scaled to the entire bitmap bounds
Pdf.DrawPage(Bmp.Canvas.Handle, 0, 0, BmpWidth, BmpHeight);
// ... encode to JPEG
finally
Bmp.Free;
end;
end;
De belangrijkste opmerking hierbij is FillRect. Vrijwel alle PDF-documenten hebben een lege (transparante) achtergrond, in plaats van een witte. Zonder de achtergrond te vullen, zal de gerenderde bitmap een willekeurige opvulling voor GDI hebben - waarschijnlijk ondoorzichtig zwart - waardoor al uw tekst en lijntekeningen die op wit bedoeld waren, in plaats daarvan donkerder zijn na het rasteren
Coderen naar TJPEGImage en opslaan
Zodra de onbewerkte TBitmap de render opslaat, brengt u de afbeelding over naar een TJPEGImage uit de Vcl.Imaging.jpeg-unit voor compressie, en schrijft u naar een bestand of stream
uses
Vcl.Imaging.jpeg;
// ...
var
Jpg: TJPEGImage;
begin
Jpg := TJPEGImage.Create;
try
// Transfer the DIB payload
Jpg.Assign(Bmp);
// Optionally balance quality versus output file size
Jpg.CompressionQuality := 85;
Jpg.SaveToFile('page_1.jpg');
finally
Jpg.Free;
end;
end;
Het Assign-commando verwerkt de kleurruimte-conversie (normaal BGR naar YCbCr in de codec). Omdat CompressionQuality de bestandsgrootte direct beïnvloedt, is the standaard 90 een goede balans; verlaag deze naar 75 of 80 voor bestandsarchivering indien visuele degradatie is toegestaan, maar let op: artefacten van de compressie verstoren scherpe vectorranden aanzienlijk sneller dan bij fotografie
De methoden en concepten die hier worden geschetst, maken deel uit van de PDFium Component, de primaire bibliotheek van losLab Software voor het programmeren en genereren van documenten