ฝังรูปภาพลงในเอกสาร
ภาพรวมโดยย่อ
หัวข้อที่มีชื่อว่า “ภาพรวมโดยย่อ”วางรูปภาพแบบราสเตอร์ที่ตำแหน่งสัมบูรณ์ด้วยความกว้างที่กำหนดไว้อย่างชัดเจน หากละเว้นความสูง NextPDF จะคำนวณค่านั้นจากอัตราส่วนภาพของต้นฉบับ สูตรนี้อ้างอิงจาก examples/07-images.php คุณสามารถใช้ไฟล์ JPEG, PNG, GIF, BMP, WebP และ AVIF ได้
NextPDF ฝังรูปภาพในรูปแบบ image XObject ตาม ISO 32000-2 โดย image dictionary ระบุความกว้าง ความสูง และจำนวนบิตต่อองค์ประกอบไว้อย่างชัดเจน
การติดตั้ง
หัวข้อที่มีชื่อว่า “การติดตั้ง”composer require nextpdf/core:^3API image() เป็นส่วนหนึ่งของ Core คุณไม่จำเป็นต้องใช้สิ่งอื่นเพิ่มเติมเพื่อฝังไฟล์ที่มีอยู่แล้ว ตัวอย่างประกอบสร้างรูปภาพทดสอบด้วย GD จึงต้องใช้ ext-gd API เสถียรมาตั้งแต่เวอร์ชัน 1.0.0 และทำงานบนเมทริกซ์ backport 8.1–8.4
ภาพรวมเชิงแนวคิด
หัวข้อที่มีชื่อว่า “ภาพรวมเชิงแนวคิด”image($file, x, y, width, height) โหลดไฟล์ผ่าน image registry ถอดรหัส แล้ววางลงในเอกสาร registry จะตรวจสอบความถูกต้องของพาธก่อนถอดรหัส และปฏิเสธพาธใด ๆ ที่มี NUL byte หรือมีลักษณะเป็น Uniform Resource Locator (URL) scheme (scheme://…) image() อ่านเฉพาะไฟล์ในเครื่องเท่านั้น ไม่อ่าน URL จากระยะไกล registry ยังปฏิเสธค่า width หรือ height ที่ไม่เป็นบวกด้วย
การวางใช้ current transformation matrix เพื่อแมป unit square ของรูปภาพลงในสี่เหลี่ยมผืนผ้าเป้าหมาย ISO 32000-2 §8.8 กำหนดให้ใช้ตัวดำเนินการ cm ภายในคู่ q/Q สำหรับการวางนี้ การแปลงจึงยังคงแยกจากกัน ราสเตอร์ที่ถอดรหัสแล้วจะกลายเป็น image XObject ค่า BitsPerComponent เป็นค่าที่จำเป็นและต้องเป็นหนึ่งใน 1, 2, 4, 8 หรือ 16 (§8.9.5)
ขอบเขตของ API
หัวข้อที่มีชื่อว่า “ขอบเขตของ API”ขอบเขตของ API สร้างจาก PHPDoc สูตรนี้ใช้เมธอดเดียว:
image(string $file, ?float $x = null, ?float $y = null, ?float $width = null, ?float $height = null): static— ฝังและวางรูปภาพแบบราสเตอร์ในเครื่อง ละเว้นheightเพื่อรักษาอัตราส่วนภาพของต้นฉบับ เมธอดนี้ปฏิเสธพาธแบบ URL-scheme พาธที่มี NUL byte และมิติที่ไม่เป็นบวก โดยจะโยน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');ตัวอย่างโค้ด — สำหรับใช้งานจริง
หัวข้อที่มีชื่อว่า “ตัวอย่างโค้ด — สำหรับใช้งานจริง”ตัวอย่างที่สมบูรณ์และพร้อมใช้กับ harness นี้สร้างรูปภาพทดสอบแบบกำหนดได้ด้วย 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ให้ดาวน์โหลดทรัพยากรไปยังไฟล์ในเครื่องก่อน แล้วจึงส่งพาธนั้นเข้าไป ตัวโหลดจะไม่ดึงข้อมูลผ่านเครือข่ายให้คุณ นี่คือมาตรการป้องกัน Server-Side Request Forgery (SSRF) ที่ออกแบบไว้อย่างจงใจ - มิติที่ไม่เป็นบวกจะโยนข้อยกเว้น ค่า
width <= 0หรือheight <= 0จะทำให้เกิดPageLayoutExceptionหากต้องการใช้ขนาดตามธรรมชาติ ให้ละเว้นอาร์กิวเมนต์แทนการส่งค่า0 - พาธที่มี NUL byte จะถูกปฏิเสธ พาธที่มี
\0จะถูกปฏิเสธ มาตรการนี้ป้องกันพาธแบบ poison-null-byte ให้ตรวจสอบความถูกต้องของชื่อไฟล์ที่ผู้ใช้ระบุ - อัตราส่วนภาพ ส่งเฉพาะ
widthหรือเฉพาะheightอย่างใดอย่างหนึ่ง เพื่อปรับขนาดตามสัดส่วน การส่งทั้งสองค่าอาจทำให้รูปภาพบิดเบี้ยว - การฝังไฟล์เดียวกันสองครั้ง ใช้พาธเดียวซ้ำเพื่อปรับขนาดผ่าน transformation matrix เอนจินจะไม่ถอดรหัสไบต์ที่เหมือนกันซ้ำ ควรเลือกใช้พาธซ้ำมากกว่าการทำสำเนาไฟล์
ประสิทธิภาพ
หัวข้อที่มีชื่อว่า “ประสิทธิภาพ”ต้นทุนการถอดรหัสแปรผันตามจำนวนพิกเซลของต้นฉบับ งบประมาณจึงกำหนดไว้ที่ 96 MB เพื่อรองรับภาพถ่ายขนาดปานกลาง การวางพาธเดิมซ้ำมีต้นทุนน้อย: เพิ่มเพียงหนึ่ง Do บวกกับหนึ่ง cm ไม่ใช่การถอดรหัสครั้งที่สอง การลดขนาดตามความกว้างไม่ได้ลดจำนวนพิกเซลที่จัดเก็บไว้ หากขนาดเอกสารเป็นเรื่องสำคัญ ให้ปรับขนาดรูปภาพต้นฉบับขนาดใหญ่ไว้ล่วงหน้า
หมายเหตุด้านความปลอดภัย
หัวข้อที่มีชื่อว่า “หมายเหตุด้านความปลอดภัย”การปฏิเสธ URL-scheme และ NUL byte ช่วยป้องกัน SSRF และ path injection image() ไม่สามารถถูกหลอกให้ดึง http://… หรือลัดผ่าน null byte ได้ ถึงกระนั้น ให้ถือว่าชื่อไฟล์ที่ผู้ใช้ระบุเป็นข้อมูลที่ไม่น่าเชื่อถือเสมอ จงแปลงพาธเหล่านั้นเทียบกับไดเรกทอรีฐานที่อนุญาตก่อนเรียก image() เมื่อไฟล์เป็นไฟล์ที่ผู้ใช้อัปโหลด การถอดรหัสรูปภาพจะทำงานบนไบต์ที่ผู้โจมตีควบคุมได้ จำกัดขนาดอินพุตและพิจารณาถอดรหัสใน worker ที่แยกออกมาต่างหาก
ความสอดคล้องตามมาตรฐาน
หัวข้อที่มีชื่อว่า “ความสอดคล้องตามมาตรฐาน”| ข้อความระบุ | ข้อกำหนด | ข้อ | รหัสอ้างอิง (reference_id) |
|---|---|---|---|
| image dictionary ระบุความกว้าง ความสูง และจำนวนบิตต่อองค์ประกอบไว้อย่างชัดเจน | 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 ใน trailer และค่า date atoms ดังนั้น harness จะตัดส่วนเหล่านั้นออก แล้วเปรียบเทียบโครงสร้างที่ปรับให้เป็นมาตรฐานด้วย qpdf สูตรนี้อธิบายวิธีที่ NextPDF สร้างโครงสร้างดังกล่าว ไม่ได้กล่าวอ้างความสอดคล้องตาม ISO 32000-2 แบบครอบคลุมทั้งหมด
บริบทเชิงพาณิชย์
หัวข้อที่มีชื่อว่า “บริบทเชิงพาณิชย์”ไม่เกี่ยวข้อง การฝังรูปภาพแบบราสเตอร์เป็นความสามารถของ Core โดยไม่ถูกกั้นไว้สำหรับ Premium