Nhúng hình ảnh vào tài liệu
Tổng quan nhanh
Phần tiêu đề “Tổng quan nhanh”Đặ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.
Cài đặt
Phần tiêu đề “Cài đặt”composer require nextpdf/core:^3API 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.
Tổng quan khái niệm
Phần tiêu đề “Tổng quan khái niệm”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
Phần tiêu đề “Giao diện API”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ỏ quaheightđể 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émPageLayoutException.
Ví dụ mã — bắt đầu nhanh
Phần tiêu đề “Ví dụ mã — bắt đầu nhanh”<?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ụ mã — sản xuất
Phần tiêu đề “Ví dụ mã — sản xuất”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émPageLayoutException. 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 <= 0hoặcheight <= 0sẽ làm phát sinhPageLayoutException. Để dùng kích thước tự nhiên, hãy bỏ qua tham số thay vì truyền0. - Đường dẫn chứa byte NUL bị từ chối. Đường dẫn chứa
\0sẽ 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
widthhoặ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.
Hiệu năng
Phần tiêu đề “Hiệu năng”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.
Ghi chú bảo mật
Phần tiêu đề “Ghi chú bảo mật”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.
Tuân thủ
Phần tiêu đề “Tuân thủ”| Tuyên bố | Đặc tả | Điều khoản | reference_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.
Bối cảnh thương mại
Phần tiêu đề “Bối cảnh thương mại”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.