Bỏ qua để đến nội dung

Nhúng hình ảnh vào tài liệu

Đặt hình ảnh raster tại vị trí tuyệt đối với chiều rộng được chỉ định rõ. Bỏ qua chiều cao để NextPDF tự tính từ tỷ lệ khung hình của nguồn. Công thức này dựa trên examples/07-images.php. Bạn có thể dùng các tệp JPEG, PNG, GIF, BMP, WebP và AVIF.

NextPDF nhúng hình ảnh dưới dạng image XObject theo ISO 32000-2. Image dictionary khai báo tường minh chiều rộng, chiều cao và số bit trên mỗi thành phần.

Terminal window
composer require nextpdf/core:^3

API image() thuộc Core. Bạn không cần thêm gì khác để nhúng một tệp đã có sẵn. Ví dụ đi kèm tạo hình ảnh thử nghiệm bằng GD nên cần ext-gd. API này ổn định từ 1.0.0 và chạy trên ma trận backport 8.1–8.4.

image($file, x, y, width, height) tải tệp thông qua image registry, giải mã rồi đặt hình ảnh vào tài liệu. Registry xác thực đường dẫn trước khi giải mã. Nó từ chối mọi đường dẫn chứa byte NUL hoặc có dạng scheme Uniform Resource Locator (URL) (scheme://…). image() chỉ đọc các tệp cục bộ, không bao giờ đọc một URL từ xa. Registry cũng từ chối giá trị width hoặc height không dương.

Quá trình đặt hình ảnh dùng current transformation matrix để ánh xạ hình vuông đơn vị của hình ảnh vào hình chữ nhật đích. ISO 32000-2 §8.8 chỉ định toán tử cm bên trong cặp q/Q cho thao tác đặt này, nhờ đó phép biến đổi vẫn được cô lập. Dữ liệu raster đã giải mã trở thành image XObject. BitsPerComponent của nó là bắt buộc và phải là một trong các giá trị 1, 2, 4, 8 hoặc 16 (§8.9.5).

Giao diện API được tạo từ PHPDoc. Công thức này dùng một phương thức:

  • image(string $file, ?float $x = null, ?float $y = null, ?float $width = null, ?float $height = null): static — nhúng và đặt hình ảnh raster cục bộ. Bỏ qua height để giữ tỷ lệ khung hình của nguồn. Phương thức này từ chối các đường dẫn dạng URL-scheme, đường dẫn chứa byte NUL và các kích thước không dương bằng cách ném 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');

Ví dụ hoàn chỉnh, sẵn sàng cho harness, tạo một hình ảnh thử nghiệm tất định bằng GD nên công thức vẫn khép kín. Ví dụ tuân theo NEXTPDF_COOKBOOK_OUTPUT và không tự đưa vào bất kỳ entropy nào.

<?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);
}

Trường hợp đặc biệt & điểm cần lưu ý

Phần tiêu đề “Trường hợp đặc biệt & điểm cần lưu ý”
  • Không dùng URL từ xa. Đường dẫn khớp với scheme://… sẽ bị từ chối bằng cách ném PageLayoutException. Hãy tải tài nguyên về một tệp cục bộ trước rồi truyền đường dẫn đó vào. Trình tải sẽ không lấy dữ liệu qua mạng thay bạn. Đây là biện pháp bảo vệ Server-Side Request Forgery (SSRF) có chủ đích.
  • Kích thước không dương sẽ gây ngoại lệ. width <= 0 hoặc height <= 0 sẽ làm phát sinh PageLayoutException. Để dùng kích thước tự nhiên, hãy bỏ qua tham số thay vì truyền 0.
  • Đường dẫn chứa byte NUL bị từ chối. Đường dẫn chứa \0 sẽ bị từ chối. Cơ chế này bảo vệ khỏi các đường dẫn poison-null-byte. Hãy xác thực tên tệp do người dùng cung cấp.
  • Tỷ lệ khung hình. Chỉ truyền width hoặc chỉ height để co giãn theo tỷ lệ. Truyền cả hai giá trị có thể làm hình ảnh bị méo.
  • Cùng một tệp được nhúng hai lần. Hãy tái sử dụng cùng một đường dẫn để co giãn thông qua transformation matrix. Engine không giải mã lại các byte giống hệt nhau. Hãy ưu tiên tái sử dụng đường dẫn thay vì sao chép tệp.

Chi phí giải mã tỷ lệ thuận với số pixel của nguồn, nên ngân sách 96 MB đủ cho một ảnh cỡ vừa. Đặt lại hình từ cùng một đường dẫn tốn rất ít: chỉ thêm một Do cùng một cm, chứ không phải một lần giải mã thứ hai. Thu nhỏ theo chiều rộng không làm giảm số pixel được lưu trữ. Hãy điều chỉnh kích thước trước cho các hình ảnh nguồn lớn nếu kích thước tài liệu là yếu tố quan trọng.

Việc từ chối URL-scheme và byte NUL bảo vệ chống lại SSRF và tấn công chèn đường dẫn. image() không thể bị đánh lừa để tải http://… hoặc vượt qua một byte null. Dù vậy, hãy coi các tên tệp do người dùng cung cấp là không đáng tin cậy. Hãy phân giải chúng trong phạm vi một thư mục cơ sở được cho phép trước khi bạn gọi image(). Với tệp do người dùng tải lên, quá trình giải mã hình ảnh chạy trên các byte chịu ảnh hưởng của kẻ tấn công. Hãy giới hạn kích thước đầu vào và cân nhắc giải mã trong một worker cô lập.

Tuyên bốĐặc tảĐiều khoảnreference_id
Một image dictionary chỉ định tường minh chiều rộng, chiều cao và số bit trên mỗi thành phần.ISO 32000-2§8.9.5
BitsPerComponent là bắt buộc và có giá trị 1, 2, 4, 8 hoặc 16.ISO 32000-2§8.9.5
Một hình ảnh được đặt bằng toán tử cm bên trong q/Q.ISO 32000-2§8.8

Hồ sơ khả năng tái lập — cấu trúc. Các byte hình ảnh là tất định với một nguồn cố định. Mỗi tài liệu được lưu vẫn chứa một trailer /ID và các atom ngày tháng, nên harness loại bỏ những thành phần đó và so sánh cấu trúc đã được chuẩn hóa bằng qpdf. Công thức này mô tả cách NextPDF tạo ra cấu trúc. Nó không đưa ra tuyên bố tuân thủ ISO 32000-2 toàn diện.

Không áp dụng. Nhúng hình ảnh raster là một khả năng của Core và không nằm sau rào cản Premium.