เพิ่มลายน้ำข้อความ ลายน้ำรูปภาพ หรือพื้นหลังลงในหน้า
ภาพรวมโดยย่อ
หัวข้อที่มีชื่อว่า “ภาพรวมโดยย่อ”คุณสามารถเพิ่มเครื่องหมาย “DRAFT” หรือ “CONFIDENTIAL” พาดทับทุกหน้า หรือวางโลโก้แบบจางไว้ด้านหลังเนื้อหาได้ สูตรนี้เพิ่มทั้งสองอย่างให้กับหน้าใน NextPDF core ผ่าน public document surface ได้แก่ setAlpha() สำหรับความโปร่งใส startTransform() / rotate() / stopTransform() สำหรับตราประทับแนวทแยง text() สำหรับเครื่องหมาย และ image() สำหรับพื้นหลังแบบ raster
ลายน้ำกับพื้นหลังต่างกันที่ตัวเลือกเดียว นั่นคือลำดับการวาด
- พื้นหลัง: วาดก่อน แล้วจึงเขียนเนื้อหาของหน้าทับลงไป เครื่องหมายจะอยู่ด้านหลังข้อความ
- ลายน้ำแบบซ้อนทับ: เขียนเนื้อหาของหน้าก่อน แล้วจึงวาดเครื่องหมายทับลงไป เครื่องหมายจะอยู่ด้านบนสุด
NextPDF วาดเนื้อหาตามลำดับการเรียกใช้ของคุณ ดังนั้นลำดับการเรียกใช้จึงกำหนดลำดับเลเยอร์ ไม่มี “background mode” แยกต่างหาก คุณกำหนดเลเยอร์ได้จากจังหวะที่เลือกวาด
ข้อกำหนดเบื้องต้น: ต้องมีการติดตั้ง core (composer require nextpdf/core:^3) ที่ใช้งานได้ และสำหรับพื้นหลังรูปภาพ ต้องมีไฟล์ raster ที่อ่านได้ (PNG, JPEG หรือ WebP) บนดิสก์ ไปป์ไลน์ทั้งหมดทำงานภายในโพรเซส โดยไม่ใช้ headless browser หรือการเรียกผ่านเครือข่าย
การติดตั้ง
หัวข้อที่มีชื่อว่า “การติดตั้ง”composer require nextpdf/core:^3ภาพรวมเชิงแนวคิด
หัวข้อที่มีชื่อว่า “ภาพรวมเชิงแนวคิด”เครื่องหมายแต่ละรายการที่คุณเพิ่มคือเนื้อหาของหน้าตามปกติ ซึ่งวาดผ่าน graphics state public surface ส่วนประกอบสามส่วนทำงานร่วมกันเพื่อสร้างลายน้ำ:
-
ความโปร่งใส
setAlpha(float $alpha, BlendMode $mode = BlendMode::Normal)กำหนดความทึบของการเติมสีให้กับทุกสิ่งที่คุณวาดหลังจากนั้น ตั้งแต่0.0(มองไม่เห็น) ไปจนถึง1.0(ทึบแสง) โดยทั่วไปลายน้ำจะทำงานได้ดีที่สุดที่0.1ถึง0.3เพื่อให้เนื้อหาด้านล่างยังคงอ่านได้ blend mode มาจาก enumNextPDF\Graphics\BlendModeตัวอย่างเช่นBlendMode::Multiplyจะทำให้บริเวณที่เครื่องหมายซ้อนทับกับเนื้อหามืดลง -
การหมุน ตราประทับแนวทแยงคือข้อความที่หมุนรอบจุดหมุน
startTransform()บันทึก graphics staterotate(float $angle, float $x, float $y)หมุนระบบพิกัดทวนเข็มนาฬิการอบ($x, $y)และstopTransform()กู้คืนสถานะที่บันทึกไว้ การคร่อมเครื่องหมายไว้ในบล็อกการแปลงช่วยป้องกันไม่ให้การหมุนและ alpha ส่งผลต่อส่วนที่เหลือของหน้า -
ตัวเครื่องหมาย
text(float $x, float $y, string $text)เขียนสตริงที่ตำแหน่งสัมบูรณ์โดยใช้ฟอนต์ สี และ alpha ปัจจุบันimage(string $file, ?float $x, ?float $y, ?float $width, ?float $height)วางรูปภาพแบบ raster ซึ่งเป็นพื้นฐานของลายน้ำรูปภาพหรือพื้นหลังแบบเต็มหน้า
graphics state กู้คืนได้อย่างเรียบร้อยเพราะ startTransform() และ stopTransform() คร่อมการเปลี่ยนแปลงไว้ ค่า setAlpha() จะคงอยู่จนกว่าคุณจะกำหนดอีกครั้ง หากเนื้อหาที่ตามมาต้องทึบแสงเต็มที่ ให้รีเซ็ตความทึบเป็น 1.0 หลังจากวาดเครื่องหมาย รูปแบบที่ปลอดภัยกว่าซึ่งแสดงด้านล่างจะวาดเครื่องหมายไว้ภายในบล็อกการแปลงของตัวเอง และกำหนด alpha ของเนื้อหาหน้าอย่างชัดเจน
แพ็กเกจนี้ยังมี value object NextPDF\Graphics\Watermark และ NextPDF\Graphics\WatermarkPosition ด้วย Watermark เป็นตัวเก็บการตั้งค่าแบบไม่เปลี่ยนรูปสำหรับข้อความ ขนาดฟอนต์ มุม สี แฟล็กการซ้อนทับ และค่าตำแหน่งที่เตรียมไว้ เช่น WatermarkPosition::Diagonal อ็อบเจกต์เหล่านี้จำลองพารามิเตอร์ของลายน้ำ สูตรนี้วาดเครื่องหมายด้วยเมธอดข้างต้นซึ่งเขียนลงหน้าโดยตรง ดังนั้นผลลัพธ์จึงไปถึงสตรีมเนื้อหาของหน้าโดยตรง
พื้นผิว API
หัวข้อที่มีชื่อว่า “พื้นผิว API”เมธอดทั้งหมดด้านล่างนี้เป็น public บน NextPDF\Core\Document และคืนค่า static จึงสามารถเรียกต่อกันเป็นลูกโซ่ได้
setAlpha(float $alpha, BlendMode $mode = BlendMode::Normal): static: กำหนดความทึบของการเติมสี (0.0-1.0) และ blend mode สำหรับเนื้อหาที่ตามมาstartTransform(): static: บันทึก graphics state (ปล่อยq)rotate(float $angle, float $x = 0, float $y = 0): static: หมุนระบบพิกัด$angleองศาทวนเข็มนาฬิการอบจุดหมุน($x, $y)stopTransform(): static: คืนค่าสถานะที่บันทึกโดยstartTransform()(ปล่อยQ) โดยยกเลิกการหมุนและการเปลี่ยน alpha พร้อมกันsetFont(string $family, string $style = '', float $size = 12.0): static: เลือกฟอนต์สำหรับเครื่องหมาย ฟอนต์ตระกูล Base-14helveticaมีให้ใช้เสมอและไม่ต้องใช้ไฟล์ฟอนต์setTextColor(int $r, int $g = -1, int $b = -1): static: กำหนดสีเครื่องหมายเป็นค่าแดง เขียว น้ำเงิน (หรือค่าระดับสีเทาค่าเดียว)text(float $x, float $y, string $text): static: เขียนเครื่องหมายที่ตำแหน่งสัมบูรณ์image(string $file, ?float $x = null, ?float $y = null, ?float $width = null, ?float $height = null): static: วางรูปภาพแบบ raster ซึ่งเป็นพื้นฐานของลายน้ำรูปภาพหรือพื้นหลังแบบเต็มหน้าgetPageWidth(): float/getPageHeight(): float: อ่านขนาดหน้าปัจจุบันเป็นพอยต์ เพื่อให้คุณจัดเครื่องหมายไว้กึ่งกลางได้
ชนิดที่รองรับอยู่ภายใต้ NextPDF\Graphics ได้แก่ enum BlendMode value object Color และคู่การตั้งค่า Watermark / WatermarkPosition
ตัวอย่างโค้ด — เริ่มต้นอย่างรวดเร็ว
หัวข้อที่มีชื่อว่า “ตัวอย่างโค้ด — เริ่มต้นอย่างรวดเร็ว”ตัวอย่างนี้สร้างหนึ่งหน้า วาดตราประทับ “DRAFT” แนวทแยงแบบจางทับเนื้อหา และบันทึกไฟล์ ตัวอย่างนี้เว้นการจัดการข้อผิดพลาดไว้เพื่อแสดงรูปแบบการเรียกใช้ ตัวอย่างสำหรับใช้งานจริงด้านล่างได้เพิ่มการป้องกันครบถ้วน
<?php
declare(strict_types=1);
require_once __DIR__ . '/vendor/autoload.php';
use NextPDF\Core\Document;
$doc = Document::createStandalone();$doc->addPage();
// Page content first, so the watermark lands on top of it.$doc->setFont('helvetica', '', 12);$doc->text(20.0, 40.0, 'Quarterly report: internal review copy.');
// Watermark second: a translucent, rotated stamp through the page center.$pivotX = $doc->getPageWidth() / 2.0;$pivotY = $doc->getPageHeight() / 2.0;
$doc->startTransform();$doc->setAlpha(0.15);$doc->setTextColor(150, 150, 150);$doc->setFont('helvetica', 'B', 72);$doc->rotate(45.0, $pivotX, $pivotY);$doc->text($pivotX - 110.0, $pivotY, 'DRAFT');$doc->stopTransform();
file_put_contents(__DIR__ . '/watermarked.pdf', $doc->getPdfData());ตัวอย่างโค้ด — สำหรับใช้งานจริง
หัวข้อที่มีชื่อว่า “ตัวอย่างโค้ด — สำหรับใช้งานจริง”โปรแกรมแบบสมบูรณ์ในตัวนี้วาดลายน้ำข้อความแนวทแยงทับเนื้อหาที่สร้างขึ้น เมื่อคุณระบุพาทของรูปภาพผ่านตัวแปรสภาพแวดล้อม NEXTPDF_WATERMARK_IMAGE โปรแกรมจะวางรูปภาพนั้นเป็นพื้นหลังแบบจางที่จัดกึ่งกลางบนหน้าที่สอง โปรแกรมตรวจสอบความถูกต้องของพาทรูปภาพก่อนใช้งาน จับ exception ของ NextPDF ที่เฉพาะเจาะจงที่สุด และเขียนผลลัพธ์ลงพาทที่ควบคุมโดยเซิร์ฟเวอร์ แทนที่เนื้อหาในหน่วยความจำด้วยเนื้อหาของคุณเอง แล้วเชื่อมต่อผลลัพธ์เข้ากับเลเยอร์การตอบสนองหรือการจัดเก็บของคุณ
<?php
declare(strict_types=1);
require_once __DIR__ . '/vendor/autoload.php';
use NextPDF\Core\Document;use NextPDF\Exception\ImageProcessingException;use NextPDF\Exception\NextPdfException;use NextPDF\Exception\PageLayoutException;
/** * Paint a translucent, rotated text stamp across the current page. * * The mark is bracketed in a transform block so the rotation and the alpha * change are undone together and never leak into later content. * * @param non-empty-string $mark The watermark text (for example "CONFIDENTIAL") */function paintTextWatermark(Document $doc, string $mark): void{ $pivotX = $doc->getPageWidth() / 2.0; $pivotY = $doc->getPageHeight() / 2.0;
// Estimate the mark width so the rotated text sits centered on the pivot. // Helvetica averages ~0.5 em per glyph; half the width offsets the origin. $fontSize = 64.0; $halfWidth = (\strlen($mark) * $fontSize * 0.5) / 2.0;
$doc->startTransform(); $doc->setAlpha(0.12); $doc->setTextColor(120, 120, 120); $doc->setFont('helvetica', 'B', $fontSize); $doc->rotate(45.0, $pivotX, $pivotY); $doc->text($pivotX - $halfWidth, $pivotY, $mark); $doc->stopTransform();}
/** * Place a raster image as a faint, full-page background behind later content. * * The image is drawn first and at low opacity; page content written after this * call sits over it. The path is validated by the caller before it arrives. * * @param non-empty-string $imagePath A readable raster image (PNG, JPEG, WebP) * * @throws ImageProcessingException If the file is missing, unreadable, or corrupt. * @throws PageLayoutException If the placement coordinates are rejected. */function paintImageBackground(Document $doc, string $imagePath): void{ $doc->startTransform(); $doc->setAlpha(0.08); // Cover the full page: origin at the top-left, sized to the page box. $doc->image( file: $imagePath, x: 0.0, y: 0.0, width: $doc->getPageWidth(), height: $doc->getPageHeight(), ); $doc->stopTransform();}
$doc = Document::createStandalone();$doc->setTitle('Watermark and background sample');
// Page 1: content first, then an overlay text watermark on top.$doc->addPage();$doc->setAlpha(1.0);$doc->setTextColor(0, 0, 0);$doc->setFont('helvetica', '', 12);$doc->text(20.0, 40.0, 'Quarterly report: internal review copy.');
try { paintTextWatermark($doc, 'CONFIDENTIAL');} catch (PageLayoutException $e) { // Raised if a coordinate or page state is rejected while placing the mark. throw new RuntimeException( sprintf('Watermark placement failed: %s', $e->getConstraint()), previous: $e, );}
// Page 2: an optional image background, then content over it.$imagePath = getenv('NEXTPDF_WATERMARK_IMAGE');
if ($imagePath !== false && $imagePath !== '') { // Validate the path before touching the image loader: reject NUL bytes, // require a real readable file, and resolve it to defeat path traversal. if (str_contains($imagePath, "\0")) { throw new RuntimeException('Image path must not contain NUL bytes.'); }
$resolved = realpath($imagePath);
if ($resolved === false || !is_file($resolved) || !is_readable($resolved)) { throw new RuntimeException( sprintf('Background image "%s" is not a readable file.', $imagePath), ); }
$doc->addPage();
try { paintImageBackground($doc, $resolved); } catch (ImageProcessingException $e) { // Raised when the file cannot be decoded as a supported raster format. throw new RuntimeException( sprintf( 'Background image rejected (%s, op "%s").', $e->getFormat(), $e->getOperation(), ), previous: $e, ); } catch (PageLayoutException $e) { throw new RuntimeException( sprintf('Background placement failed: %s', $e->getConstraint()), previous: $e, ); }
$doc->setAlpha(1.0); $doc->setTextColor(0, 0, 0); $doc->setFont('helvetica', '', 12); $doc->text(20.0, 40.0, 'Page two over a faint background.');}
try { $pdf = $doc->getPdfData();} catch (NextPdfException $e) { // Base of the NextPDF exception hierarchy: any output-stage failure. throw new RuntimeException( sprintf('Document output failed: %s', $e->getMessage()), previous: $e, );}
$out = getenv('NEXTPDF_COOKBOOK_OUTPUT');$path = $out !== false && $out !== '' ? $out : __DIR__ . '/watermarked.pdf';
if (file_put_contents($path, $pdf) === false) { throw new RuntimeException(sprintf('Could not write PDF to "%s".', $path));}
printf("Wrote %d-byte PDF to %s\n", strlen($pdf), $path);เอาต์พุตมาตรฐาน (STDOUT) ที่คาดหวัง (ขนาดไบต์ขึ้นอยู่กับบิลด์และว่าคุณได้ระบุรูปภาพหรือไม่):
Wrote <n>-byte PDF to <path>กรณีขอบและข้อควรระวัง
หัวข้อที่มีชื่อว่า “กรณีขอบและข้อควรระวัง”- ลำดับเลเยอร์คือลำดับการเรียกใช้ พื้นหลังคือเนื้อหาที่วาดก่อนเนื้อหาของหน้า ลายน้ำแบบซ้อนทับคือเนื้อหาที่วาดหลังจากนั้น ไม่มีแฟล็กใดที่จัดลำดับเลเยอร์ใหม่ ให้ย้ายตำแหน่งการเรียกใช้แทน
- Alpha จะคงอยู่จนกว่าจะรีเซ็ต
setAlpha()เปลี่ยนสถานะให้กับทุกสิ่งที่วาดหลังจากนั้น ให้คร่อมเครื่องหมายไว้ในstartTransform()/stopTransform()ซึ่งจะคืนค่า alpha เดิม หรือเรียกsetAlpha(1.0)ก่อนเนื้อหาที่ทึบแสง ตัวอย่างสำหรับใช้งานจริงทำทั้งสองอย่าง - รักษาสมดุลของทุกบล็อกการแปลง แต่ละ
startTransform()ต้องมีstopTransform()ที่จับคู่กัน บล็อกที่ไม่สมดุลจะทิ้งการหมุนหรือ alpha ให้มีผลต่อเนื้อหาที่ตามมา และการขาดstopTransform()จะสร้างความไม่สมดุลของ graphics state ที่ตัวเขียนปฏิเสธในขั้นตอนเอาต์พุต rotate()หมุนรอบจุดในพิกัดผู้ใช้ จุดหมุน($x, $y)อยู่ในหน่วยผู้ใช้ที่วัดจากมุมบนซ้ายของหน้า ในกรอบเดียวกับtext()สำหรับเส้นทแยงที่ผ่านกึ่งกลาง ให้ใช้จุดกึ่งกลางหน้า (getPageWidth() / 2,getPageHeight() / 2)- ข้อความที่หมุนต้องชดเชยความกว้างด้วยตนเอง
text()วางจุดเริ่มต้นของสตริง ไม่ได้จัดกึ่งกลางให้คุณ ลบความกว้างข้อความโดยประมาณราวครึ่งหนึ่งออกจาก X ของจุดหมุน เพื่อให้เครื่องหมายที่หมุนคร่อมกึ่งกลาง ตามที่ฟังก์ชันตัวช่วยทำ - รูปภาพปรับขนาดตามกล่องที่คุณส่งให้
image()ยืดรูปภาพ raster ให้พอดีกับwidthและheightที่คุณกำหนด สำหรับพื้นหลังแบบเต็มหน้า ให้ส่งความกว้างและความสูงของหน้า สำหรับโลโก้ที่มุม ให้ส่งขนาดตามธรรมชาติของโลโก้ ขนาดที่เป็นศูนย์หรือค่าลบจะทำให้เกิดPageLayoutException image()ปฏิเสธ URL และไบต์ NUL พาทแบบscheme://หรือไบต์ NUL ใน$fileจะทำให้เกิดPageLayoutExceptionก่อนการถอดรหัสใด ๆ ให้ส่งเฉพาะพาทในเครื่องที่ผ่านการตรวจสอบแล้วเท่านั้น- เครื่องหมายเป็นเนื้อหาที่มองเห็นได้ ลายน้ำที่วาดด้วยวิธีนี้เป็นเนื้อหาของหน้าจริง ไม่ใช่คำอธิบายประกอบที่ซ่อนอยู่ ผู้ที่มีไฟล์นี้สามารถอ่านได้ เครื่องหมายนี้เป็นเพียงสัญญาณทางสายตา ไม่ใช่การควบคุมการเข้าถึง
ประสิทธิภาพ
หัวข้อที่มีชื่อว่า “ประสิทธิภาพ”ลายน้ำข้อความใช้ตัวดำเนินการของสตรีมเนื้อหาเพียงไม่กี่ตัวต่อหน้า และเพิ่มเวลาหรือหน่วยความจำเพียงเล็กน้อยจนแทบไม่มีนัยสำคัญ ลายน้ำหรือพื้นหลังแบบรูปภาพมีต้นทุนจากการถอดรหัส raster หนึ่งครั้งบวกกับไบต์รูปภาพที่ฝังอยู่ในเอาต์พุต การใช้รูปภาพเดียวกันซ้ำในหลายหน้าจะนำ XObject ที่ถอดรหัสแล้วกลับมาใช้ผ่านแคชรูปภาพ คุณจึงเสียต้นทุนการถอดรหัสเพียงครั้งเดียว ปรับขนาดรูปภาพพื้นหลังให้พอดีกับกล่องแสดงผลก่อนฝัง ภาพถ่ายขนาด 4000 px ที่ย่อลงบนหน้ากระดาษ letter จะยังเก็บไบต์ที่ผู้อ่านไม่มีวันเห็นไว้ ลายน้ำข้อความหน้าเดียวโดยทั่วไปอยู่ในกรอบงบประมาณเวลารวม 500 ms และหน่วยความจำสูงสุด 32 MB ได้อย่างเหลือเฟือ พื้นหลังแบบรูปภาพจะแปรผันตามขนาดที่ถอดรหัสแล้วของ raster ต้นทาง
หมายเหตุด้านความปลอดภัย
หัวข้อที่มีชื่อว่า “หมายเหตุด้านความปลอดภัย”ไปป์ไลน์ทำงานภายในโพรเซส ไม่มีไบต์ของเอกสารออกจากโฮสต์ และไม่มีการเรียกผ่านเครือข่าย ให้ถือว่าพาทรูปภาพใด ๆ ที่มาจากภายนอกโค้ดของคุณเป็นอินพุตที่ไม่น่าเชื่อถือ
- ตรวจสอบความถูกต้องของพาทรูปภาพก่อนใช้งาน ปฏิเสธไบต์ NUL แปลงพาทเป็นพาทสมบูรณ์ด้วย
realpath()และยืนยันis_file()และis_readable()ก่อนที่คุณจะเรียกimage()เช่นเดียวกับที่ตัวอย่างสำหรับใช้งานจริงทำ วิธีนี้ปิดกั้น path traversal และปฏิเสธไดเรกทอรีและลิงก์ที่ปลายทางหายไปตั้งแต่ต้น - อย่านำฟิลด์จากคำขอมาแทรกลงในพาทเด็ดขาด ให้ได้พาทรูปภาพและพาทเอาต์พุตมาจากค่าที่ควบคุมโดยเซิร์ฟเวอร์ ไม่ใช่จากพารามิเตอร์ของคำขอ วิธีนี้ป้องกันไม่ให้คุณอ่านหรือเขียนไฟล์นอกไดเรกทอรีที่ตั้งใจไว้
- ให้ถือว่ารูปภาพที่ไม่น่าเชื่อถือเป็นอินพุตที่เป็นอันตราย raster ที่ผิดรูปแบบจะทำให้เกิด
ImageProcessingExceptionแทนที่จะทำให้เอกสารเสียหาย และตัวโหลดจำกัดขนาดรูปภาพเพื่อต้านอินพุตแบบ decompression bomb จับ exception และปฏิเสธการอัปโหลด อย่าลองใหม่โดยไม่พิจารณา - ลายน้ำไม่ใช่ที่เก็บความลับ เครื่องหมายเป็นเนื้อหาที่มองเห็นได้ อย่าเข้ารหัสข้อมูลรับรอง โทเค็น หรือตัวระบุภายในไว้ในลายน้ำหรือพื้นหลังที่คุณส่งกลับไปยังไคลเอนต์
ความสอดคล้องตามมาตรฐาน
หัวข้อที่มีชื่อว่า “ความสอดคล้องตามมาตรฐาน”สูตรนี้ไม่ได้อ้างความสอดคล้องตามมาตรฐานในเชิงบรรทัดฐานด้วยตัวเอง สูตรนี้ประกอบขึ้นจาก primitive สาธารณะสำหรับ alpha การแปลง ข้อความ และรูปภาพ primitive แต่ละตัวปล่อยตัวดำเนินการของสตรีมเนื้อหา PDF มาตรฐาน graphics state ถูกแยกออกด้วยตัวดำเนินการ q / Q ที่ startTransform() และ stopTransform() ปล่อยออกมา และความโปร่งใสถูกส่งผ่านพารามิเตอร์ graphics state แบบ ExtGState เอาต์พุตเน้นความสามารถในการทำซ้ำเชิงโครงสร้างมากกว่าความเสถียรระดับไบต์ ดังนั้นหน้านี้จึงประกาศโปรไฟล์ความสามารถในการทำซ้ำแบบ structural สำหรับรายละเอียดระดับตัวดำเนินการเกี่ยวกับพื้นผิวการแปลงและ graphics state โปรดดู การอ้างอิงโมดูล Graphics
ดูเพิ่มเติม
หัวข้อที่มีชื่อว่า “ดูเพิ่มเติม”- การอ้างอิงโมดูล Graphics: พื้นผิวพาท การแปลง สี และ graphics state ทั้งหมดที่อยู่เบื้องหลังเมธอดเหล่านี้
- ฝังรูปภาพ: โหลด ปรับขนาด และวางรูปภาพแบบ raster ซึ่งเป็นพื้นฐานของลายน้ำหรือพื้นหลังแบบรูปภาพ
- การไล่ระดับสีและความโปร่งใส: พื้นผิว alpha และ blend mode อย่างละเอียด รวมถึงการเติมสีแบบโปร่งแสง
- แปลงปริภูมิพิกัด: หมุน ปรับขนาด และเลื่อนเนื้อหาด้วยบล็อกการแปลงที่สมดุล
- การจัดการข้อผิดพลาดที่รับรู้ exception: ลำดับชั้น exception ของ NextPDF ที่อยู่เบื้องหลัง
ImageProcessingException,PageLayoutExceptionและNextPdfException