SVG ใน ReportLab: รักษาพาธโลโก้ให้คมชัดใน PDF ที่สร้างขึ้น
วางโลโก้ SVG ใน PDF ของ ReportLab ด้วย svglib รักษาสัดส่วน และตรวจไฟล์สุดท้ายว่ามีพาธเวกเตอร์ ขนาดถูกต้อง และรายละเอียดไม่หาย
ในหน้านี้
ใช้ svglib.svg2rlg() อ่าน SVG เป็น Drawing ของ ReportLab แล้ววางด้วย renderPDF.draw() กำหนดกรอบบนหน้าที่วัดขนาดชัดเจนและใช้ตัวคูณมาตราส่วนเดียวกับทั้งสองแกน วิธีนี้เก็บรูปทรงโลโก้ที่เหมาะสมเป็นคำสั่งวาด PDF แทนการแทรกภาพหน้าจอบิตแมป
สำหรับการส่งออกไฟล์เดี่ยวที่ไม่มีเลย์เอาต์เอกสาร กระบวนการกำหนดขนาด CairoSVG เปรียบเทียบพิกเซล PNG ขนาดหน้า PDF และ DPI
การทดสอบที่มีประโยชน์คือ PDF สุดท้าย: ตรายังรักษาสัดส่วน สี และช่องเปิดเล็กตามขนาดที่เอกสารต้องการหรือไม่? การเรียก Python สำเร็จไม่ตอบคำถามเหล่านั้น ตัวอย่างด้านล่างวางตราต้นฉบับเดียวกันสองครั้งและตรวจไฟล์ที่สร้าง
หากมีโลโก้เป็นเวกเตอร์ที่แก้ไขได้อยู่แล้ว ให้เริ่มจากนั้น หากเหลือเพียง PNG หรือ JPG ให้กู้คืนไฟล์หลักเวกเตอร์ก่อนสร้างเอกสาร ภาพถ่ายและกราฟตัวเลขต้องเลือกต้นฉบับต่างกัน
นำเข้างานภาพเป็น drawing
กระบวนการในเอกสาร svglib แปลง SVG เป็นวัตถุ drawing ของ ReportLab คู่มือกราฟิก ReportLab อธิบายว่าสามารถเรนเดอร์ drawing บน canvas หรือใช้เป็น flowable ของ Platypus ได้ สำหรับตัวอย่างนี้ canvas ให้แต่ละตำแหน่งมีพิกัดและขนาดชัดเจน
เรารันตัวอย่างด้วย Python 3.12, svglib 2.2.0 และ ReportLab 4.4.9 ติดตั้งสองแพ็กเกจที่ล็อกเวอร์ชันในสภาพแวดล้อมโปรเจกต์:
python -m pip install "svglib==2.2.0" "reportlab==4.4.9"บันทึกตราเล็กนี้เป็น logo.svg มีสามพาธสีเติมทึบ ไม่มีภาพลิงก์ ฟอนต์ หรือเอฟเฟกต์ นี่เป็นงานเขียนเองสำหรับการสาธิต ไม่ใช่ผลแปลง PerfectVector
<svg xmlns="http://www.w3.org/2000/svg"
width="240" height="120" viewBox="0 0 240 120">
<path fill="#1c625e" d="M0 120 L60 0 L120 120 Z"/>
<path fill="#e5a340" d="M96 120 L156 24 L216 120 Z"/>
<path fill="#163451" d="M228 12 L240 12 L240 108 L228 108 Z"/>
</svg>viewBox ของ SVG อธิบายสี่เหลี่ยมพิกัดภายใน width และ height ของ drawing ที่นำเข้าบอกขนาดที่ควรใช้วางใน PDF อ่านค่าเหล่านั้นแทนการสมมติว่าพิกเซล SVG เท่ากับพอยต์ PDF
สำหรับไฟล์นี้ svglib 2.2.0 คืนขนาด 180 × 90 พอยต์ เอกสารหน่วยปัจจุบัน แมปพิกเซล CSS เป็น 0.75 พอยต์ PDF ตัวอย่างเก่าอาจมีสมมติฐานต่างกัน จึงตรวจขนาดเมื่ออัปเกรดกระบวนการเดิม
จัดโลโก้ให้พอดีโดยไม่ยืดผิดสัดส่วน
บันทึกต่อไปนี้เป็น place_logo.py ข้าง SVG แล้วรัน python place_logo.py ตำแหน่งหน้าและขนาดกรอบทั้งหมดในที่นี้เป็นพอยต์ PDF หนึ่งนิ้วมี 72 พอยต์ จุดกำเนิด canvas ปริยายอยู่ล่างซ้ายตาม คู่มือ canvas ของ ReportLab
from reportlab.graphics import renderPDF
from reportlab.pdfgen import canvas
from svglib.svglib import svg2rlg
def draw_svg_in_box(pdf, drawing, x, y, box_w, box_h):
if drawing.width <= 0 or drawing.height <= 0:
raise ValueError("The SVG needs positive dimensions")
factor = min(box_w / drawing.width, box_h / drawing.height)
pdf.saveState()
pdf.translate(x, y)
pdf.scale(factor, factor)
renderPDF.draw(drawing, pdf, 0, 0)
pdf.restoreState()
drawing = svg2rlg("logo.svg")
if drawing is None:
raise ValueError("SVG could not be loaded")
pdf = canvas.Canvas("logo.pdf", pagesize=(640, 360))
draw_svg_in_box(pdf, drawing, 40, 154, 144, 72)
draw_svg_in_box(pdf, drawing, 302, 126, 288, 144)
pdf.save()min() เลือกด้านที่จำกัดขนาด เพื่อให้ drawing พอดีภายในกรอบ การใช้ตัวคูณเดียวสำหรับ X และ Y รักษาสัดส่วน ฟังก์ชันนี้ยึด drawing ที่มุมล่างซ้ายของกรอบ พื้นที่เหลืออยู่ด้านบนหรือขวา จัดกึ่งกลางแยกหากเลย์เอาต์ต้องการ
การแปลง canvas เป็นแบบชั่วคราว restoreState() ป้องกันมาตราส่วนโลโก้ไม่ให้เปลี่ยนข้อความหรือองค์ประกอบหน้าที่ตามมา และ drawing ต้นฉบับยังใช้วางครั้งที่สองได้
ในการทดสอบ ตัวคูณทั้งสองคือ 0.8 และ 1.6 ให้งานภาพขนาด 144 × 72 pt และ 288 × 144 pt พรีวิวเพิ่มป้ายและพื้นหลังให้ตำแหน่งเดียวกันทั้งสองเพื่อเปรียบเทียบขนาดง่าย

สำหรับเอกสาร Platypus นำ drawing เข้า story เป็น flowable ได้ หลังปรับเนื้อหาด้วย drawing.scale(factor, factor) ให้อัปเดต drawing.width และ drawing.height ด้วยตัวคูณเดียวเพื่อให้เลย์เอาต์ใช้พื้นที่ใหม่ ทำจาก drawing ใหม่เมื่อใช้ขนาดต่างกัน ตัวอย่าง canvas ด้านบนเลี่ยงการเปลี่ยน drawing เอง
ตรวจรูปทรงและรูปลักษณ์แยกกัน
เราตรวจสตรีมเนื้อหา PDF ทดสอบด้วย pypdf 6.10.0 พบคำสั่งเริ่มพาธหกรายการตรงกับพาธตราสามพาธที่วาดสองครั้ง และไม่มีภาพบนหน้า เรายังเรนเดอร์ทั้งหน้าด้วย Poppler และตรวจตราทั้งสอง รูปทรง การซ้อน แท่งแนวตั้ง และสัดส่วนตรงกับตำแหน่งที่ตั้งใจ
ผลสังเกตเหล่านั้นใช้กับตัวอย่างเรียบง่ายนี้ การนับพาธเพียงอย่างเดียวไม่พิสูจน์ว่าฟีเจอร์ทั้งหมดของ SVG อื่นเรนเดอร์ถูกต้อง เช่นเดียวกันการซูม PDF บนหน้าจอไม่สามารถบอกอย่างเด็ดขาดว่ามีคำสั่งเวกเตอร์หรือบิตแมปใหญ่
สำหรับเอกสารของคุณ:
- เปรียบเทียบ PDF สุดท้ายกับ SVG ในเบราว์เซอร์หรือโปรแกรมแก้ไข มองหารายละเอียดหาย สีเติมเปลี่ยน การตัดภาพ และพื้นที่ขาวผิดคาด
- ตรวจตราตามขนาดเอกสารที่ตั้งใจ ซึ่งช่องแคบและเส้นละเอียดต้องยังอ่านได้
- ตรวจวัตถุรูปภาพ PDF หากกระบวนการต้องการเวกเตอร์ คำนึงถึงภาพถ่ายที่ตั้งใจไว้ส่วนอื่นของหน้าด้วย
- เก็บไฟล์หลัก SVG คู่กับโค้ดสร้างเอกสาร ตรวจ PDF ใหม่หลังเปลี่ยนงานภาพหรือ dependency เรนเดอร์
SVG เองอาจมีภาพราสเตอร์ การอ่านกรอบห่อนั้นไม่กู้พาธจากพิกเซล วิธีวินิจฉัยภาพฝัง ช่วยแยกไฟล์หลักเวกเตอร์จาก SVG ที่ยังมีบิตแมป
จัดการฟีเจอร์ที่ตัวนำเข้าไม่สร้างตาม
ข้อจำกัด svglib ปัจจุบัน รวมมาสก์และองค์ประกอบ foreignObject ที่ไม่รองรับ กฎ @import ของสไตล์ชีตที่ถูกละเลย และข้อจำกัด CSS กับการตัดภาพ พรีวิวเบราว์เซอร์จึงไม่ทดแทนการทดสอบตัวนำเข้า PDF
เก็บสำเนาไฟล์หลักก่อนลดความซับซ้อน เมื่อโลโก้พึ่งเอฟเฟกต์ที่ไม่รองรับ ให้พิจารณาสร้างส่วนนั้นใหม่เป็นรูปทรงทั่วไปหรือใช้วิธีส่งออกอื่นที่ตรวจได้ เก็บราสเตอร์ต้นฉบับเมื่อรูปลักษณ์ภาพถ่ายสำคัญกว่าการแก้พาธ ภาพที่รวมทุกชั้นเป็นภาพเดียวรักษารูปลักษณ์ได้ แต่เปลี่ยนข้อกำหนดเวกเตอร์
สำหรับตัวอักษร เลือกอย่างตั้งใจระหว่างข้อความเอกสารกับงานเส้นรอบรูป การเก็บคำเป็นข้อความให้แก้และค้นหาได้ แต่ต้องมีฟอนต์ที่ตั้งใจในกระบวนการเอกสาร การทำตัวอักษรโลโก้ที่อนุมัติเป็นเส้นรอบรูปเก็บรูปทรงแต่เสียการแก้ข้อความปกติ ตราที่เป็นพาธล้วนของเราไม่ทดสอบฟอนต์ ใช้ตัวอย่างตัวอักษรจริงก่อนพึ่งกระบวนการเดียวกัน
หากประกอบเอกสารในระบบจัดเรียงพิมพ์แทน Python กระบวนการ SVG ใน LaTeX อธิบายอีกวิธีสำหรับกราฟิกและป้ายข้อความ
กู้คืนโลโก้ที่มีเพียงราสเตอร์ก่อนวาง PDF
PNG เก่าบนเทมเพลตใบแจ้งหนี้เหมาะจะกู้เวกเตอร์เมื่อต้นฉบับโลโก้หาย ด้วย ตัวแปลงโลโก้เป็นเวกเตอร์ของ PerfectVector คุณพรีวิวงานราสเตอร์เป็น SVG ตรวจเส้นรอบรูปและช่องเปิด แล้วดาวน์โหลดไฟล์สำหรับประเมินในกระบวนการเอกสารได้
ตรวจตัวอักษรเล็กและกรอบก่อนนำเข้า วาดใหม่หรือเรียงข้อความใหม่สำหรับส่วนที่ต้องใช้ตัวอักษรตรงเป๊ะ และลบรูปทรงพื้นหลังที่ไม่ต้องการในโปรแกรมแก้ไข คู่มือแปลงโลโก้เป็นเวกเตอร์ ครอบคลุมการเลือกจากต้นฉบับสู่ไฟล์หลักละเอียดขึ้น
จากนั้นรันการนำเข้า ReportLab จริงและตรวจ PDF ตามด้านบน ผลลากพาธดีต้องผ่านตัวนำเข้าและพอดีเอกสารด้วย PerfectVector ให้พาธงานภาพ ไม่ได้เลือกพิกัด ReportLab ลงทะเบียนฟอนต์เอกสาร หรือตรวจ PDF ผลลัพธ์ สำหรับกราฟ ให้สร้างใหม่จากข้อมูลและต้นฉบับโปรแกรมพล็อตแทนลากพาธป้ายหรือค่าที่พล็อต
คำถามที่พบบ่อย
ส่ง SVG ให้ ReportLab เป็นภาพบิตแมปทั่วไปได้หรือไม่? ใช้ svglib สร้าง Drawing และเรนเดอร์ด้วย renderPDF สำหรับกระบวนการเวกเตอร์นี้ การแปลง SVG เป็น PNG ก่อนให้การแทรกราสเตอร์แทน
ทำไม SVG ที่นำเข้าเล็กกว่าตัวอย่างเก่า? svglib 2.2.0 ที่ทดสอบแมปพิกเซล CSS เป็นพอยต์ PDF ด้วยตัวคูณ 0.75 อ่านขนาด drawing ที่คืนมาและจัดให้พอดีกรอบชัดเจนแทนพึ่งสมมติฐานพิกเซลต่อพอยต์เก่า
วิธีนี้รักษาเอฟเฟกต์ SVG ทุกอย่างหรือไม่? ไม่ ตัวนำเข้ามีข้อจำกัดฟีเจอร์ในเอกสาร รวมมาสก์และ foreignObject เปรียบเทียบ PDF ที่ส่งออกกับงานที่ตั้งใจ แม้สคริปต์จบโดยไม่มีข้อผิดพลาด
ควรแปลงภาพหน้าจอกราฟเป็นเวกเตอร์ไหม? สร้างกราฟใหม่จากข้อมูลและต้นฉบับโปรแกรมพล็อตเมื่อทำได้ เก็บการลากพาธโลโก้ไว้สำหรับงานตกแต่งที่เหมาะสมซึ่งต้นฉบับแก้ไขได้หายไป
แหล่งอ้างอิง
- svglib — เอกสารแพ็กเกจและหน่วย — การแปลง SVG เป็น Drawing การติดตั้ง และขนาดพอยต์ PDF
- ReportLab — กราฟิก — วัตถุ Drawing การเรนเดอร์ PDF และการใช้เป็น flowable ของ Platypus
- ReportLab — กราฟิกและข้อความด้วย pdfgen — พิกัด canvas พอยต์ และการแปลง
- svglib — ข้อจำกัดที่ทราบ — ข้อจำกัดนำเข้าที่ต้องตรวจ PDF สุดท้าย
เก็บต้นฉบับที่แก้ไขได้เมื่อมี หากเหลือเพียงโลโก้ราสเตอร์ ให้ เตรียมโลโก้ SVG สำหรับประเมิน ตรวจพาธ แล้ววางตามขนาดที่ต้องการและตรวจ PDF สุดท้าย
เพิ่มเติมจากบล็อก

ภาพ SVG ใน fpdf2: เก็บพาธใน PDF จาก Python
วางโลโก้ SVG ใน PDF จาก Python ด้วย fpdf2 ควบคุมขนาด ตรวจพาธที่บันทึก และวินิจฉัยข้อความหรือรูปร่างที่หายก่อนเลือกใช้ราสเตอร์แทน

SVG ใน PDFKit: วางโลโก้เวกเตอร์โดยไม่แบนเป็นภาพ
แทรกโลโก้ SVG ทั้งไฟล์ในเอกสาร PDFKit ตั้งขนาดเป็นพอยต์ และตรวจ PDF ที่บันทึกว่ามีพาธ ช่องเปิด คุณสมบัติที่หาย และภาพฝังหรือไม่