コンテンツにスキップ

ドキュメントに画像を埋め込む

ラスター画像を明示的な幅で絶対位置に配置します。高さを省略すると、NextPDF はソースのアスペクト比から高さを導き出します。このレシピは examples/07-images.php に従います。NextPDF は JPEG、PNG、GIF、BMP、WebP、AVIF を受け付けます。

埋め込まれた画像は ISO 32000-2 の image XObject になります。その辞書には、幅、高さ、コンポーネントあたりのビット数が明示的に記述されます。

Terminal window
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 サーフェスは 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 <= 0PageLayoutException を発生させます。本来のサイズを使用するには、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 による制限はありません。