Ga naar inhoud

Afbeeldingen in een document insluiten

Plaats een rasterafbeelding op een absolute positie met een expliciete breedte. Laat de hoogte weg; NextPDF leidt die af uit de beeldverhouding van de bron. Dit recipe volgt examples/07-images.php. Je kunt JPEG-, PNG-, GIF-, BMP-, WebP- en AVIF-bestanden gebruiken.

NextPDF sluit de afbeelding in als een ISO 32000-2 image XObject. De image dictionary vermeldt de breedte, hoogte en bits per component expliciet.

Terminal window
composer require nextpdf/core:^3

De image()-API maakt deel uit van Core. Je hebt verder niets nodig om een bestaand bestand in te sluiten. Het bijbehorende voorbeeld genereert een testafbeelding met GD en heeft daarom ext-gd nodig. De API is stabiel sinds 1.0.0 en werkt met de 8.1–8.4-backportmatrix.

image($file, x, y, width, height) laadt het bestand via het image registry, decodeert het en plaatst het. Het registry valideert het pad voordat het met decoderen begint. Het wijst elk pad af dat een NUL-byte bevat of eruitziet als een Uniform Resource Locator (URL)-schema (scheme://…). image() leest uitsluitend lokale bestanden, nooit een externe URL. Het registry wijst ook een niet-positieve width of height af.

De plaatsing gebruikt de huidige transformatiematrix om het eenheidsvierkant van de afbeelding op de doelrechthoek af te beelden. ISO 32000-2 §8.8 specificeert de cm-operator binnen een q/Q-paar voor deze plaatsing, zodat de transformatie geïsoleerd blijft. Het gedecodeerde raster wordt een image XObject. De bijbehorende BitsPerComponent is verplicht en moet 1, 2, 4, 8 of 16 zijn (§8.9.5).

Het API-oppervlak wordt gegenereerd uit PHPDoc. Dit recipe gebruikt één methode:

  • image(string $file, ?float $x = null, ?float $y = null, ?float $width = null, ?float $height = null): static — sluit een lokale rasterafbeelding in en plaatst die. Laat height weg om de beeldverhouding van de bron te behouden. De methode wijst paden met een URL-schema, paden met een NUL-byte en niet-positieve afmetingen af met een PageLayoutException.
<?php
declare(strict_types=1);
require_once __DIR__ . '/vendor/autoload.php';
use NextPDF\Core\Document;
$doc = Document::createStandalone();
$doc->addPage();
// Absolute position; height inferred from the source aspect ratio.
$doc->image(__DIR__ . '/logo.png', x: 15, y: 30, width: 80);
$doc->save(getenv('NEXTPDF_COOKBOOK_OUTPUT') ?: __DIR__ . '/images.pdf');

Dit volledige voorbeeld is klaar voor de harness en genereert een deterministische testafbeelding met GD, zodat het recipe zelfstandig blijft. Het respecteert NEXTPDF_COOKBOOK_OUTPUT en legt zelf geen entropie vast.

<?php
declare(strict_types=1);
require_once __DIR__ . '/vendor/autoload.php';
use NextPDF\Core\Document;
if (!\extension_loaded('gd')) {
fwrite(STDERR, "ext-gd required for the self-contained test image\n");
exit(1);
}
// Build a deterministic test image (fixed pixels — no entropy).
$imgPath = \tempnam(\sys_get_temp_dir(), 'npf') . '.png';
$img = \imagecreatetruecolor(200, 100);
if ($img === false) {
fwrite(STDERR, "GD imagecreatetruecolor failed\n");
exit(1);
}
$bg = (int) \imagecolorallocate($img, 30, 58, 138);
$fg = (int) \imagecolorallocate($img, 255, 255, 255);
\imagefilledrectangle($img, 0, 0, 199, 99, $bg);
\imagestring($img, 5, 40, 40, 'NextPDF Image', $fg);
\imagepng($img, $imgPath);
\imagedestroy($img);
try {
$doc = Document::createStandalone();
$doc->setTitle('Image Embedding');
$doc->addPage();
$doc->setFont('helvetica', 'B', 18);
$doc->cell(0, 12, 'Image Embedding', newLine: true);
$doc->ln(5);
// Absolute placement; width fixed, height from aspect ratio.
$doc->image($imgPath, x: 15, y: 50, width: 80);
// Same image, narrower — scaled down by the CTM, not re-decoded.
$doc->image($imgPath, x: 15, y: 105, width: 40);
$out = getenv('NEXTPDF_COOKBOOK_OUTPUT') ?: __DIR__ . '/images.pdf';
$doc->save($out);
echo "Created images.pdf\n";
} finally {
@\unlink($imgPath);
}
  • Geen externe URL’s. Een pad dat overeenkomt met scheme://… wordt afgewezen met een PageLayoutException. Download de asset eerst naar een lokaal bestand en geef daarna dat pad door. De loader haalt niets voor je op via het netwerk. Dit is een bewuste beveiliging tegen Server-Side Request Forgery (SSRF).
  • Niet-positieve afmetingen leveren een uitzondering op. Een width <= 0 of height <= 0 leidt tot een PageLayoutException. Laat het argument weg in plaats van 0 door te geven om de natuurlijke grootte te gebruiken.
  • Pad met NUL-byte wordt afgewezen. Een pad dat \0 bevat, wordt afgewezen. Dit beschermt tegen poison-null-byte-paden. Valideer door gebruikers aangeleverde bestandsnamen.
  • Beeldverhouding. Geef alleen width door, of alleen height, om proportioneel te schalen. Als je beide waarden doorgeeft, kan de afbeelding vervormen.
  • Hetzelfde bestand twee keer insluiten. Hergebruik één pad om via de transformatiematrix te schalen. De engine decodeert identieke bytes niet opnieuw. Geef de voorkeur aan hergebruik van het pad boven het dupliceren van bestanden.

De decodeerkosten zijn evenredig met het aantal bronpixels; daarom is het budget 96 MB om een gematigde foto toe te staan. Hetzelfde pad nogmaals plaatsen kost weinig: één extra Do plus een cm, geen tweede decodering. Schalen naar een kleinere breedte vermindert de opgeslagen pixels niet. Verklein grote bronafbeeldingen vooraf als de documentgrootte belangrijk is.

Het afwijzen van URL-schema’s en NUL-bytes beschermt tegen SSRF en padinjectie. image() kan niet worden misleid om http://… op te halen of voorbij een NUL-byte te navigeren. Behandel door gebruikers aangeleverde bestandsnamen desondanks als niet-vertrouwd. Beperk ze tot een toegestane basismap voordat je image() aanroept. Wanneer het bestand door een gebruiker is geüpload, wordt de afbeelding gedecodeerd op bytes die door een aanvaller kunnen zijn beïnvloed. Begrens de invoergrootte en overweeg het decoderen in een geïsoleerde worker.

BeweringSpecificatieArtikelreference_id
Een image dictionary specificeert de breedte, hoogte en bits per component expliciet.ISO 32000-2§8.9.5
BitsPerComponent is verplicht en is 1, 2, 4, 8 of 16.ISO 32000-2§8.9.5
Een afbeelding wordt geplaatst door de cm-operator binnen q/Q.ISO 32000-2§8.8

Reproduceerbaarheidsprofiel — structureel. Afbeeldingsbytes zijn deterministisch voor een vaste bron. Elk opgeslagen document bevat nog steeds een trailer-/ID en datumatomen. Daarom verwijdert de harness die en vergelijkt de qpdf-genormaliseerde structuur. Dit recipe beschrijft hoe NextPDF de structuur produceert. Het doet geen algemene claim van ISO 32000-2-conformiteit.

Niet van toepassing. Het insluiten van rasterafbeeldingen is een Core-functie zonder Premium-drempel.