ドキュメントに画像を埋め込む
ラスター画像を明示的な幅で絶対位置に配置します。高さを省略すると、NextPDF はソースのアスペクト比から高さを導き出します。このレシピは examples/07-images.php に従います。NextPDF は JPEG、PNG、GIF、BMP、WebP、AVIF を受け付けます。
埋め込まれた画像は ISO 32000-2 の image XObject になります。その辞書には、幅、高さ、コンポーネントあたりのビット数が明示的に記述されます。
インストール
「インストール」という見出しのセクションcomposer require nextpdf/core:^3この image() API は Core の一部です。既存のファイルを埋め込むために追加のものは必要ありません。付属のサンプルのように GD でテスト画像を生成するには、ext-gd が必要です。この API は 1.0.0 以降安定しており、8.1~8.4 のバックポートマトリックスで動作します。
概念的な概要
「概念的な概要」という見出しのセクションimage($file, x, y, width, height) は、画像レジストリを通じてファイルを読み込み、デコードして配置します。レジストリは、デコード前にパスを検証します。NUL バイトを含むパスと、URL スキーム(scheme://…)のように見えるパスを拒否します。これは、image() がローカルファイルのみを読み込み、リモート URL は決して読み込まないためです。レジストリは、正でない width または height も拒否します。
配置では、現在の変換行列を使用して、画像の単位正方形を対象の矩形にマッピングします。ISO 32000-2 §8.8 では、この処理のために cm 演算子を q/Q のペアの内側で指定するため、変換は分離された状態を保ちます。デコードされたラスターは image XObject になります。その BitsPerComponent は必須であり、1、2、4、8、16 のいずれかでなければなりません(§8.9.5)。
API サーフェス
「API サーフェス」という見出しのセクションAPI サーフェスは PHPDoc から自動生成されます。このレシピは 1 つのメソッドに依存します。
image(string $file, ?float $x = null, ?float $y = null, ?float $width = null, ?float $height = null): static— ローカルのラスター画像を埋め込んで配置します。ソースのアスペクト比を維持するにはheightを省略します。URL スキームのパス、NUL バイトを含むパス、正でない寸法は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');コードサンプル — 本番
「コードサンプル — 本番」という見出しのセクションこれは、ハーネスに対応した完全なサンプルです。GD で確定的なテスト画像を生成するため、レシピは自己完結しています。このサンプルは NEXTPDF_COOKBOOK_OUTPUT を尊重し、独自のエントロピーを固定しません。
<?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);}エッジケースと注意点
「エッジケースと注意点」という見出しのセクション- リモート URL は不可。
scheme://…に一致するパスはPageLayoutExceptionで拒否されます。まずアセットをローカルファイルにダウンロードし、そのパスを渡してください。ローダーはネットワーク経由で取得を行いません。これは意図的な SSRF 対策です。 - 正でない寸法は例外を投げます。
width <= 0またはheight <= 0はPageLayoutExceptionを発生させます。本来のサイズを使用するには、0を渡すのではなく、引数を省略してください。 - NUL バイトのパスは拒否されます。
\0を含むパスは拒否されます。これはポイズンヌルバイト対策です。ユーザー指定のファイル名は検証してください。 - アスペクト比。 比率を保ったまま拡大縮小するには、
widthのみ、またはheightのみを渡します。両方を渡すと画像が歪むことがあります。 - 同じファイルを 2 回埋め込む場合。 1 つのパスを再利用すると、変換行列を通じて拡大縮小されます。エンジンは同一のバイトを再デコードしません。ファイルを複製するよりも、パスを再利用することをお勧めします。
パフォーマンス
「パフォーマンス」という見出しのセクションデコードコストはソースのピクセル数に比例するため、ほどほどのサイズの写真を扱えるように予算は 96 MB に設定されています。同じパスを再配置するコストはわずかです。2 回目のデコードではなく、Do が 1 つと cm が 1 つ追加されるだけです。幅による縮小では、保存されるピクセルは減りません。ドキュメントのサイズが重要な場合は、大きなソース画像を事前にリサイズしてください。
セキュリティに関する注意
「セキュリティに関する注意」という見出しのセクションURL スキームと NUL バイトの拒否は、SSRF およびパスインジェクションへの対策です。image() に http://… を取得させたり、ヌルバイトを越えてトラバースさせたりすることはできません。それでも、ユーザー指定のファイル名は信頼できないものとして扱ってください。image() を呼び出す前に、許可されたベースディレクトリを基準にしてそれらを resolve(解決)してください。ファイルがユーザーによってアップロードされる場合、画像のデコードは攻撃者の影響を受けたバイトに対して実行されます。入力サイズに上限を設け、分離されたワーカーでのデコードを検討してください。
| 記述 | 仕様 | 箇条 | リファレンス ID(reference_id) |
|---|---|---|---|
| 画像辞書は、幅、高さ、コンポーネントあたりのビット数を明示的に指定します。 | ISO 32000-2 | §8.9.5 | |
BitsPerComponent は必須であり、1、2、4、8、16 のいずれかです。 | ISO 32000-2 | §8.9.5 | |
画像は cm 演算子によって q/Q の内側に配置されます。 | ISO 32000-2 | §8.8 |
再現性プロファイル — 構造的。 画像のバイトは、固定されたソースに対して確定的です。保存されたすべてのドキュメントには、依然としてトレーラーの /ID と日付アトムが含まれるため、ハーネスはそれらを取り除き、qpdf で正規化された構造を比較します。このレシピは、NextPDF がどのように構造を生成するかを説明します。これは ISO 32000-2 への準拠を包括的な主張として断言するものではありません。
商用に関する補足
「商用に関する補足」という見出しのセクション該当なし。ラスター画像の埋め込みは Core の機能であり、Premium による制限はありません。