Incorporare immagini in un documento
In breve
Sezione intitolata “In breve”Posizionare un’immagine raster in posizione assoluta con una larghezza esplicita. Omettere l’altezza: NextPDF la ricava dalle proporzioni dell’immagine di origine. Questa ricetta segue examples/07-images.php. NextPDF accetta JPEG, PNG, GIF, BMP, WebP e AVIF.
Un’immagine incorporata diventa un XObject immagine secondo ISO 32000-2. Il suo dizionario dichiara esplicitamente larghezza, altezza e bit per componente.
Installazione
Sezione intitolata “Installazione”composer require nextpdf/core:^3L’API image() fa parte di Core. Incorporare un file già esistente non richiede componenti aggiuntivi. Generare un’immagine di test con GD, come nell’esempio di riferimento, richiede ext-gd. L’API è stabile da 1.0.0 e funziona sulla matrice di backport 8.1–8.4.
Panoramica concettuale
Sezione intitolata “Panoramica concettuale”image($file, x, y, width, height) carica il file tramite il registro delle immagini, lo decodifica e lo posiziona. Il registro convalida il percorso prima della decodifica. Rifiuta i percorsi che contengono un byte NUL e quelli che assomigliano a uno schema URL (scheme://…), perché image() legge solo file locali, mai URL remoti. Il registro rifiuta anche width o height non positive.
Il posizionamento usa la matrice di trasformazione corrente per mappare il quadrato unitario dell’immagine nel rettangolo di destinazione. ISO 32000-2 §8.8 specifica l’operatore cm all’interno di una coppia q/Q a questo scopo, in modo che la trasformazione rimanga isolata. Il raster decodificato diventa un XObject immagine. Il suo BitsPerComponent è obbligatorio e deve essere uno tra 1, 2, 4, 8 o 16 (§8.9.5).
Superficie dell’API
Sezione intitolata “Superficie dell’API”La superficie dell’API è generata automaticamente da PHPDoc. Questa ricetta usa un solo metodo:
image(string $file, ?float $x = null, ?float $y = null, ?float $width = null, ?float $height = null): static— incorpora e posiziona un’immagine raster locale. Omettereheightper mantenere le proporzioni dell’immagine di origine. Rifiuta i percorsi con schema URL, quelli con byte NUL e le dimensioni non positive generando unaPageLayoutException.
Esempio di codice — Avvio rapido
Sezione intitolata “Esempio di codice — Avvio rapido”<?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');Esempio di codice — Produzione
Sezione intitolata “Esempio di codice — Produzione”Questo è l’esempio completo, pronto per l’harness. Genera con GD un’immagine di test deterministica, in modo che la ricetta resti autonoma. Rispetta NEXTPDF_COOKBOOK_OUTPUT e non introduce entropia propria.
<?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);}Casi limite e insidie
Sezione intitolata “Casi limite e insidie”- Nessun URL remoto. Un percorso che corrisponde a
scheme://…viene rifiutato con unaPageLayoutException. Scaricare prima la risorsa in un file locale, quindi passare quel percorso. Il loader non effettua download dalla rete per conto dell’utente. È una protezione SSRF deliberata. - Le dimensioni non positive generano un’eccezione. Una
width <= 0o unaheight <= 0genera unaPageLayoutException. Per usare la dimensione naturale, omettere l’argomento invece di passare0. - Percorsi con byte NUL rifiutati. Un percorso che contiene
\0viene rifiutato. È una protezione contro il poison null byte. Convalidare i nomi di file forniti dall’utente. - Proporzioni. Passare solo
width, oppure soloheight, per ridimensionare in modo proporzionale. Passare entrambi può distorcere l’immagine. - Lo stesso file incorporato due volte. Riutilizzare un unico percorso applica il ridimensionamento tramite la matrice di trasformazione. Il motore non decodifica di nuovo byte identici. È preferibile riutilizzare il percorso invece di duplicare i file.
Prestazioni
Sezione intitolata “Prestazioni”Il costo della decodifica è proporzionale al numero di pixel dell’origine, quindi il budget è di 96 MB per consentire una foto di dimensioni moderate. Riposizionare lo stesso percorso è poco costoso: un Do aggiuntivo più un cm, non una seconda decodifica. Ridimensionare tramite larghezza non riduce i pixel memorizzati. Ridimensionare in anticipo le immagini di origine molto grandi se la dimensione finale del documento è importante.
Note sulla sicurezza
Sezione intitolata “Note sulla sicurezza”Il rifiuto dei percorsi con schema URL e con byte NUL protegge da SSRF e path injection. image() non può essere indotto a scaricare http://… né a proseguire oltre un null byte. Ciò nonostante, trattare i nomi di file forniti dall’utente come non attendibili. Risolverli rispetto a una directory di base consentita prima di chiamare image(). Quando il file proviene da un caricamento dell’utente, la decodifica dell’immagine viene eseguita su byte influenzabili da un aggressore. Limitare la dimensione dell’input e valutare di eseguire la decodifica in un worker isolato.
Conformità
Sezione intitolata “Conformità”| Dichiarazione | Specifica | Clausola | reference_id |
|---|---|---|---|
| Un dizionario immagine specifica in modo esplicito larghezza, altezza e bit per componente. | ISO 32000-2 | §8.9.5 | |
BitsPerComponent è obbligatorio ed è 1, 2, 4, 8 o 16. | ISO 32000-2 | §8.9.5 | |
Un’immagine viene posizionata dall’operatore cm all’interno di q/Q. | ISO 32000-2 | §8.8 |
Profilo di riproducibilità — strutturale. I byte dell’immagine sono deterministici per un’origine fissa. Ogni documento salvato include comunque un /ID nel trailer e atomi data, quindi l’harness li rimuove e confronta la struttura normalizzata con qpdf. Questa ricetta descrive la struttura prodotta da NextPDF. Non formula una dichiarazione generale di conformità a ISO 32000-2.
Contesto commerciale
Sezione intitolata “Contesto commerciale”Non applicabile. L’incorporazione di immagini raster è una funzionalità di Core senza vincoli Premium.