Przejdź do głównej zawartości

Osadzanie obrazów w dokumencie

Umieść obraz rastrowy w pozycji bezwzględnej z jawnie podaną szerokością. Pomiń wysokość, a NextPDF wyznaczy ją na podstawie proporcji obrazu źródłowego. Ten przepis opiera się na examples/07-images.php. Możesz użyć plików JPEG, PNG, GIF, BMP, WebP oraz AVIF.

NextPDF osadza obraz jako obiekt obrazu XObject zgodny z ISO 32000-2. Słownik obrazu jawnie określa szerokość, wysokość oraz liczbę bitów na składową.

Okno terminala
composer require nextpdf/core:^3

API image() jest częścią Core. Do osadzenia istniejącego pliku nie potrzeba niczego więcej. Dołączony przykład generuje obraz testowy za pomocą GD, więc wymaga ext-gd. API jest stabilne od wersji 1.0.0 i działa w ramach macierzy backportów 8.1–8.4.

image($file, x, y, width, height) wczytuje plik za pośrednictwem rejestru obrazów, dekoduje go i umieszcza. Rejestr weryfikuje ścieżkę przed dekodowaniem. Odrzuca każdą ścieżkę, która zawiera bajt NUL lub ma postać schematu Uniform Resource Locator (URL) (scheme://…). image() odczytuje wyłącznie pliki lokalne, nigdy zdalny adres URL. Rejestr odrzuca również niedodatnie wartości width lub height.

Podczas umieszczania bieżąca macierz przekształcenia odwzorowuje kwadrat jednostkowy obrazu na prostokąt docelowy. ISO 32000-2 §8.8 określa operator cm wewnątrz pary q/Q dla takiego umieszczenia, dzięki czemu przekształcenie pozostaje odizolowane. Zdekodowany raster staje się obiektem obrazu XObject. Pole BitsPerComponent jest wymagane i musi przyjmować jedną z wartości 1, 2, 4, 8 lub 16 (§8.9.5).

Powierzchnia API jest generowana na podstawie PHPDoc. Ten przepis korzysta z jednej metody:

  • image(string $file, ?float $x = null, ?float $y = null, ?float $width = null, ?float $height = null): static — osadza lokalny obraz rastrowy i umieszcza go w dokumencie. Pomiń height, aby zachować proporcje obrazu źródłowego. Odrzuca ścieżki ze schematem URL, ścieżki zawierające bajt NUL oraz niedodatnie wymiary, zgłaszając 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');

Ten kompletny przykład, gotowy do uruchomienia w środowisku testowym, generuje deterministyczny obraz testowy za pomocą GD, dzięki czemu przepis pozostaje samowystarczalny. Respektuje NEXTPDF_COOKBOOK_OUTPUT i nie wprowadza dodatkowej entropii.

<?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);
}
  • Brak zdalnych adresów URL. Ścieżka pasująca do scheme://… jest odrzucana z PageLayoutException. Najpierw pobierz zasób do pliku lokalnego, a następnie przekaż tę ścieżkę. Moduł ładujący nie pobiera danych przez sieć w imieniu aplikacji. To celowe zabezpieczenie przed atakiem Server-Side Request Forgery (SSRF).
  • Niedodatnie wymiary zgłaszają wyjątek. Wartość width <= 0 lub height <= 0 powoduje zgłoszenie PageLayoutException. Aby użyć rozmiaru naturalnego, pomiń argument zamiast przekazywać 0.
  • Ścieżka z bajtem NUL odrzucona. Ścieżka zawierająca \0 jest odrzucana. Chroni to przed ścieżkami wykorzystującymi atak typu poison null byte. Weryfikuj nazwy plików dostarczone przez użytkownika.
  • Proporcje. Przekaż tylko width albo tylko height, aby skalować proporcjonalnie. Przekazanie obu wartości może zniekształcić obraz.
  • Ten sam plik osadzony dwukrotnie. Użyj ponownie jednej ścieżki, aby skalować przez macierz przekształcenia. Silnik nie dekoduje ponownie identycznych bajtów. Preferuj ponowne wykorzystanie ścieżki zamiast duplikowania plików.

Koszt dekodowania jest proporcjonalny do liczby pikseli źródłowych, dlatego budżet 96 MB pozwala obsłużyć umiarkowanie duże zdjęcie. Ponowne umieszczenie tej samej ścieżki kosztuje niewiele: jeden dodatkowy Do oraz cm, bez ponownego dekodowania. Zmniejszenie szerokości nie redukuje liczby przechowywanych pikseli. Jeśli rozmiar dokumentu ma znaczenie, zmniejsz wcześniej duże obrazy źródłowe.

Odrzucanie schematów URL oraz bajtów NUL chroni przed atakami SSRF i wstrzykiwaniem ścieżek. image() nie da się podstępem nakłonić do pobrania http://… ani do interpretowania ścieżki poza bajtem NUL. Mimo to traktuj nazwy plików dostarczone przez użytkownika jako niezaufane. Rozwiąż je względem dozwolonego katalogu bazowego, zanim wywołasz image(). Gdy plik został przesłany przez użytkownika, dekodowanie obrazu działa na bajtach, które atakujący może kontrolować. Ogranicz rozmiar danych wejściowych i rozważ dekodowanie w odizolowanym procesie roboczym.

StwierdzenieSpecyfikacjaKlauzulareference_id
Słownik obrazu jawnie określa szerokość, wysokość oraz liczbę bitów na składową.ISO 32000-2§8.9.5
BitsPerComponent jest wymagany i przyjmuje wartość 1, 2, 4, 8 lub 16.ISO 32000-2§8.9.5
Obraz jest umieszczany za pomocą operatora cm wewnątrz q/Q.ISO 32000-2§8.8

Profil odtwarzalności — strukturalny. Bajty obrazu są deterministyczne dla ustalonego źródła. Każdy zapisany dokument nadal zawiera /ID w przyczepce oraz atomy dat, dlatego środowisko testowe usuwa je i porównuje strukturę znormalizowaną przez qpdf. Ten przepis opisuje sposób, w jaki NextPDF wytwarza strukturę. Nie formułuje ogólnego oświadczenia o zgodności z ISO 32000-2.

Nie dotyczy. Osadzanie obrazów rastrowych jest funkcją Core i nie wymaga bramki Premium.