Bilder in ein Dokument einbetten
Auf einen Blick
Abschnitt betitelt „Auf einen Blick“Platzieren Sie ein Rasterbild an einer absoluten Position mit expliziter Breite. Lassen Sie die Höhe weg; NextPDF leitet sie dann aus dem Seitenverhältnis der Quelle ab. Dieses Recipe folgt examples/07-images.php. NextPDF akzeptiert JPEG, PNG, GIF, BMP, WebP und AVIF.
Ein eingebettetes Bild wird zu einem Bild-XObject nach ISO 32000-2. Sein Dictionary gibt Breite, Höhe und Bits pro Komponente explizit an.
Installation
Abschnitt betitelt „Installation“composer require nextpdf/core:^3Die image()-API gehört zu Core. Für das Einbetten einer bereits vorhandenen Datei ist nichts Zusätzliches erforderlich. Für die Erzeugung eines Testbilds mit GD, wie im zugrunde liegenden Beispiel, ist ext-gd erforderlich. Die API ist seit 1.0.0 stabil und läuft auf der Backport-Matrix 8.1–8.4.
Konzeptueller Überblick
Abschnitt betitelt „Konzeptueller Überblick“image($file, x, y, width, height) lädt die Datei über die Image-Registry, dekodiert sie und platziert sie. Die Registry validiert den Pfad vor der Dekodierung. Sie weist Pfade ab, die ein NUL-Byte enthalten, sowie Pfade, die wie ein URL-Schema aussehen (scheme://…), weil image() ausschließlich lokale Dateien liest und niemals eine entfernte URL abruft. Die Registry weist außerdem eine nicht-positive width oder height ab.
Die Platzierung nutzt die aktuelle Transformationsmatrix, um das Einheitsquadrat des Bildes auf das Zielrechteck abzubilden. ISO 32000-2 §8.8 spezifiziert dafür den cm-Operator innerhalb eines q/Q-Paars, sodass die Transformation isoliert bleibt. Die dekodierten Rasterdaten werden zu einem Bild-XObject. Das Feld BitsPerComponent ist erforderlich und muss 1, 2, 4, 8 oder 16 sein (§8.9.5).
API-Oberfläche
Abschnitt betitelt „API-Oberfläche“Die API-Oberfläche wird automatisch aus PHPDoc generiert. Dieses Recipe stützt sich auf eine Methode:
image(string $file, ?float $x = null, ?float $y = null, ?float $width = null, ?float $height = null): static— bettet ein lokales Rasterbild ein und platziert es. Lassen Sieheightweg, um das Seitenverhältnis der Quelle zu erhalten. Weist Pfade mit URL-Schema, Pfade mit NUL-Byte und nicht-positive Abmessungen mit einerPageLayoutExceptionab.
Codebeispiel — Schnellstart
Abschnitt betitelt „Codebeispiel — Schnellstart“<?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');Codebeispiel — Produktion
Abschnitt betitelt „Codebeispiel — Produktion“Dies ist das vollständige, für den Harness geeignete Beispiel. Es erzeugt mit GD ein deterministisches Testbild, damit das Recipe in sich geschlossen bleibt. Es berücksichtigt NEXTPDF_COOKBOOK_OUTPUT und führt keine eigene Entropie ein.
<?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);}Randfälle & Stolperfallen
Abschnitt betitelt „Randfälle & Stolperfallen“- Keine entfernten URLs. Ein Pfad, der dem Muster
scheme://…entspricht, wird mit einerPageLayoutExceptionabgewiesen. Laden Sie das Asset zuerst in eine lokale Datei herunter und übergeben Sie anschließend diesen Pfad. Der Loader ruft für Sie nichts über das Netzwerk ab. Das ist eine bewusste SSRF-Schutzmaßnahme. - Nicht-positive Abmessungen lösen eine Exception aus. Eine
width <= 0oderheight <= 0löst einePageLayoutExceptionaus. Um die natürliche Größe zu nutzen, lassen Sie das Argument weg, statt0zu übergeben. - Pfade mit NUL-Byte werden abgewiesen. Ein Pfad, der
\0enthält, wird abgewiesen. Das schützt vor Poison-Null-Byte-Angriffen. Validieren Sie von Nutzern gelieferte Dateinamen. - Seitenverhältnis. Übergeben Sie nur
widthoder nurheight, um proportional zu skalieren. Beide zu übergeben kann das Bild verzerren. - Dieselbe Datei zweimal einbetten. Nutzen Sie denselben Pfad erneut, skaliert die Engine über die Transformationsmatrix. Sie dekodiert identische Bytes nicht erneut. Bevorzugen Sie die Wiederverwendung des Pfads gegenüber dem Duplizieren von Dateien.
Performance
Abschnitt betitelt „Performance“Die Dekodierkosten sind proportional zur Pixelanzahl der Quelle. Daher liegt das Budget bei 96 MB, um ein mittelgroßes Foto zu erlauben. Denselben Pfad erneut zu platzieren kostet wenig: ein zusätzliches Do plus ein cm, keine zweite Dekodierung. Das Herunterskalieren über die Breite reduziert die gespeicherten Pixel nicht. Skalieren Sie große Quellbilder vorab, wenn die Dokumentgröße wichtig ist.
Sicherheitshinweise
Abschnitt betitelt „Sicherheitshinweise“Die Abweisungen von URL-Schema und NUL-Byte schützen vor SSRF und Path-Injection. image() lässt sich nicht dazu verleiten, http://… abzurufen oder über ein Nullbyte hinaus zu navigieren. Behandeln Sie von Nutzern gelieferte Dateinamen trotzdem als nicht vertrauenswürdig. Lösen Sie sie relativ zu einem erlaubten Basisverzeichnis auf, bevor Sie image() aufrufen. Wenn die Datei von Nutzern hochgeladen wurde, verarbeitet die Bilddekodierung Bytes, die von Angreifern beeinflusst sein können. Begrenzen Sie die Eingabegröße und ziehen Sie in Betracht, in einem isolierten Worker zu dekodieren.
Konformität
Abschnitt betitelt „Konformität“| Aussage | Spezifikation | Abschnitt | reference_id |
|---|---|---|---|
| Ein Bild-Dictionary gibt Breite, Höhe und Bits pro Komponente explizit an. | ISO 32000-2 | §8.9.5 | |
BitsPerComponent ist erforderlich und beträgt 1, 2, 4, 8 oder 16. | ISO 32000-2 | §8.9.5 | |
Ein Bild wird durch den cm-Operator innerhalb von q/Q platziert. | ISO 32000-2 | §8.8 |
Reproduzierbarkeitsprofil — strukturell. Die Bild-Bytes sind für eine feste Quelle deterministisch. Jedes gespeicherte Dokument enthält dennoch ein Trailer-/ID und Datumsatome; deshalb entfernt der Harness diese Bestandteile und vergleicht die qpdf-normalisierte Struktur. Dieses Recipe beschreibt, wie NextPDF die Struktur erzeugt. Es behauptet keine pauschale ISO 32000-2-Konformität.
Kommerzieller Kontext
Abschnitt betitelt „Kommerzieller Kontext“Nicht zutreffend. Das Einbetten von Rasterbildern ist eine Core-Funktion ohne Premium-Gate.