ข้อความ SVG foreignObject: แก้ป้ายหายเมื่อส่งออก
แก้ป้าย SVG ที่เห็นในเบราว์เซอร์แต่หายเมื่อส่งออก เปรียบเทียบ foreignObject กับข้อความ SVG โดยตรง ตรวจเนมสเปซ และรักษาภาพเดิมไว้
ในหน้านี้
หากรูปร่างใน SVG คงอยู่หลังส่งออกแต่ป้ายข้อความหาย ให้ตรวจป้ายที่หายว่ามี <foreignObject> หรือไม่ มันอาจบรรจุ HTML ที่เบราว์เซอร์จัดวางได้สำเร็จ แต่ตัวเรนเดอร์ปลายทางไม่รองรับ แทนป้ายที่มีปัญหาด้วย <text> และ <tspan> ของ SVG โดยตรง หรือเลือกวิธีส่งออกที่รักษารูปลักษณ์ไว้
เริ่มจากเปิดไฟล์ที่ส่งออกจริงในเบราว์เซอร์ หากป้ายหายที่นั่นด้วย ให้ตรวจเนมสเปซ ขอบเขต และสไตล์ก่อนโทษตัวนำเข้า เก็บภาพต้นฉบับไว้ ไม่จำเป็นต้องไล่เส้นทั้งภาพเมื่อเสียเฉพาะตัวเก็บข้อความ
ทำไมภาพยังอยู่แต่ป้ายหาย
SVG ผสมรูปร่างทั่วไปกับเนื้อหาจากเนมสเปซ XML อื่นได้ ภูเขาที่วาดด้วย <path> และดวงอาทิตย์ที่วาดด้วย <circle> เป็น SVG โดยตรง ส่วนย่อหน้าภายใน <foreignObject> อาจเป็น HTML ที่มีกฎตัดบรรทัดและจัดวางของตัวเอง เอกสารอ้างอิง foreignObject ของ MDN อธิบายความต่างนี้
นามสกุล .svg จึงไม่ได้รับประกันว่าทุกส่วนใช้คุณสมบัติเรนเดอร์ชุดเดียวกัน ปลายทางอาจวาดภูเขาและดวงอาทิตย์ได้แต่ไม่แสดงย่อหน้า HTML การเปลี่ยนสีข้อความหรือเพิ่มความละเอียดส่งออกไม่ได้เพิ่มการรองรับ HTML ให้ตัวเรนเดอร์นั้น
| สิ่งที่เห็น | สิ่งที่ตรวจต่อ | วิธีแก้ที่น่าจะเหมาะ |
|---|---|---|
| รูปร่างแสดงทั้งสองที่ แต่ป้ายแสดงเฉพาะในเบราว์เซอร์ | ป้ายที่หายใช้ foreignObject หรือไม่? | แทนป้ายนั้นหรือเปลี่ยนวิธีส่งออก |
| ป้าย HTML หายในเบราว์เซอร์ด้วย | เนมสเปซ XHTML ขอบเขตที่ระบุชัด การมองเห็น และสไตล์ | แก้ตัวเก็บ HTML ก่อน |
| ข้อความ SVG โดยตรงแสดงด้วยฟอนต์หรือความยาวบรรทัดต่างไป | ฟอนต์ที่มีและตำแหน่งบรรทัดที่เลือก | จัดการฟอนต์หรือแปลงตัวอักษรฉบับสุดท้ายเป็นเส้นรอบรูป |
| ภาพส่วนใหญ่หาย | วิวพอร์ต การตัด และโครงสร้างเอกสาร | ใช้รายการตรวจ SVG ว่าง ที่ครอบคลุมกว่า |
การทดสอบเล็ก ๆ: เปลี่ยนเฉพาะป้าย
เราสร้างการ์ด SVG ขนาด 480 × 240 ที่มีพาธ วงกลม และข้อความ “Keep artwork and labels separate.” ไฟล์แรกใช้ป้าย HTML ไฟล์ที่สองคงรูปร่างเดิมและแทนเฉพาะป้ายด้วยข้อความ SVG โดยตรงแบ่งเป็นสามบรรทัดที่ระบุชัด
ในภาพตัวอย่างเบราว์เซอร์ ป้ายทั้งคู่แสดงได้ เมื่อเรนเดอร์ไฟล์เดียวกันเป็น PNG ด้วย sharp 0.34.4 ซึ่งใช้ librsvg 2.61.1 ที่บรรจุมาด้วย ได้ผลด้านล่าง: ป้าย HTML หาย แต่ป้าย SVG โดยตรงยังอยู่ ผลลัพธ์ที่ใช้ป้าย HTML ยังเหมือนตัวควบคุมที่ลบป้ายออกทุกพิกเซล นี่เป็นการทดสอบไฟล์และเวอร์ชันตัวเรนเดอร์เหล่านี้ ไม่ใช่คำตัดสินความเข้ากันได้สำหรับโปรแกรมแก้ไขทุกตัว

ไฟล์ต้นฉบับเล็กพอให้ทดลองซ้ำได้ บันทึกเป็น html-label.svg แล้วเปิดในเบราว์เซอร์:
<svg xmlns="http://www.w3.org/2000/svg"
width="480" height="240" viewBox="0 0 480 240">
<rect width="480" height="240" rx="20" fill="#f5f1e7"/>
<path d="M40 135Q90 15 140 135Z" fill="#087f75"/>
<circle cx="90" cy="95" r="18" fill="#f4bc45"/>
<foreignObject x="180" y="70" width="230" height="110">
<div xmlns="http://www.w3.org/1999/xhtml"
style="font: 28px/1.25 Arial, sans-serif; color: #172b34;">
Keep artwork and labels separate
</div>
</foreignObject>
</svg>สำหรับไฟล์ที่สอง ให้แทนองค์ประกอบ foreignObject ทั้งหมดด้วยป้ายนี้ แล้วบันทึกเป็น native-label.svg:
<text x="180" y="96" font-family="Arial, sans-serif"
font-size="28" fill="#172b34">
<tspan x="180" dy="0">Keep artwork</tspan>
<tspan x="180" dy="35">and labels</tspan>
<tspan x="180" dy="35">separate</tspan>
</text>ค่า x เริ่มแต่ละบรรทัดที่ตำแหน่งแนวนอนเดียวกัน ค่า dy เลื่อนบรรทัดถัดไปลง วิธีนี้ยอมเลิกการตัดบรรทัด HTML อัตโนมัติโดยตั้งใจ: ผู้เขียนเลือกจุดขึ้นบรรทัดและตรวจว่าพอดี MDN อธิบายการจัดตำแหน่ง tspan และlibrsvg แสดงรายการองค์ประกอบ SVG ที่รองรับ รวมถึง text และ tspan
เปิดทั้งสองไฟล์ผ่านวิธีส่งมอบจริง เช่น ตัวแปลงภาพหรือตัวสร้าง PDF เปรียบเทียบผลลัพธ์ที่บันทึก ไม่ใช่เพียงภาพตัวอย่างต้นทาง การใช้ขนาดตรงกับตัวอย่างไม่ได้รับประกันว่าฟอนต์บนเครื่องอื่นจะตรงกัน
หากป้ายหายในเบราว์เซอร์ด้วย
ตรวจไฟล์ .svg ที่บันทึกออกมา ไม่ใช่เพียงหน้าเว็บที่สร้างมัน SVG แบบ inline ใน HTML กับเอกสาร SVG อิสระมีบริบทการแยกวิเคราะห์ต่างกัน
ตัวอย่างกำหนด div ให้อยู่ใน http://www.w3.org/1999/xhtml อย่างชัดเจน MDN ระบุว่าต้องมีการประกาศเนมสเปซนี้สำหรับเนื้อหา HTML ในเอกสาร SVG อิสระ แม้ตัวอย่าง inline ใน HTML จะละได้ หากสร้างองค์ประกอบด้วย JavaScript ให้ใช้เนมสเปซที่เหมาะสมสำหรับลูก HTML; div ที่สร้างในเนมสเปซ SVG ไม่ใช่ตัวเก็บย่อหน้า HTML
จากนั้นตรวจส่วนเหล่านี้ของป้าย:
- กำหนด
widthและheightของforeignObjectให้ชัดเจนและเป็นบวกตามพื้นที่ป้ายที่ต้องการ - วางพิกัด
xและyในบริเวณภาพที่มองเห็น โดยเผื่อพื้นที่ให้ทุกบรรทัด - ตรวจ
display,visibility, opacity และสีข้อความของตัวเก็บและองค์ประกอบลูก - ยืนยันว่าไฟล์ส่งออกมีสไตล์ที่ต้องใช้ แทนการพึ่งสไตล์ชีตของหน้าเว็บรอบภาพ
ในตัวอย่าง สไตล์ป้ายทั้งหมดเป็น inline และกล่องกว้าง 230 หน่วย สูง 110 หน่วย จึงตัด CSS ภายนอกออกจากตัวแปร แต่ไม่ได้ทำให้ foreignObject ย้ายไปใช้กับตัวเรนเดอร์ที่ไม่มีคุณสมบัตินี้ได้
สำหรับการส่งออก draw.io ให้แปลงป้ายที่ต้นทาง
หากยังมีแผนภาพที่แก้ไขได้ ให้แก้การส่งออกป้ายที่นั่นก่อนแก้ XML ด้วยมือ เอกสารส่งออก draw.io ปัจจุบันมี แปลงป้ายเป็น SVG (Convert Labels to SVG) สำหรับป้ายจัดรูปแบบที่รองรับ: เลือกรูปร่างหรือเส้นเชื่อม เปิดส่วน Advanced ในแท็บ Text แล้วเปิดช่องทำเครื่องหมายนี้
ตัวเลือกนี้มีข้อจำกัด เอกสารไม่รวมป้ายที่มีโครงสร้างอย่างตาราง รายการ ลิงก์ หรือสีพื้นหลังในการแปลงนี้ หากตัวเลือกใช้ไม่ได้ การปิด ข้อความจัดรูปแบบ (Formatted Text) และ ตัดบรรทัด (Word Wrap) เป็นอีกวิธีที่เอกสารระบุ คุณอาจต้องแทรกการขึ้นบรรทัดด้วยมือและตรวจการจัดวางใหม่
ส่งออกสำเนาใหม่แล้วเปิดในแอปปลายทางอีกครั้ง การซ่อนคำเตือน “ข้อความไม่ใช่ SVG (Text is not SVG)” ไม่ได้แปลงป้าย การฝังฟอนต์แก้การพึ่งพาฟอนต์ ไม่ได้เพิ่มการรองรับการจัดวาง HTML ที่ขาดไป
สำหรับแผนภาพที่มีภาพประกอบ เก็บภาพนำเข้าแยกจากป้าย คู่มือรูปร่าง SVG ที่กำหนดเองใน draw.io อธิบายส่วนงานภาพของกระบวนการนี้
เลือกรูปแบบข้อความให้ผู้รับคนถัดไป
ข้อความ SVG โดยตรงเป็นวิธีแก้ที่มีประโยชน์เมื่อผู้รับต้องแก้ถ้อยคำ แต่ยังต้องมีฟอนต์ที่ใช้ได้ หากป้ายแสดงด้วยฟอนต์ผิด ให้ทำตามรายการตรวจฟอนต์ SVG แทนการถือว่าเป็นปัญหาตัวเก็บข้อความหายแบบเดียวกัน
| ความต้องการส่งมอบ | ทางเลือกที่ใช้งานได้ | สิ่งที่ต้องตรวจ |
|---|---|---|
| แก้ไขถ้อยคำได้ | text ของ SVG พร้อมตำแหน่งบรรทัดที่กำหนด | ฟอนต์ ความยาวบรรทัด และโปรแกรมแก้ไขปลายทาง |
| รูปทรงตัวอักษรคงที่ | แปลงตัวอักษรฉบับสุดท้ายเป็นเส้นรอบรูปในโปรแกรมต้นทาง | รูปลักษณ์ถูกต้อง; เก็บไฟล์ต้นฉบับที่แก้ไขได้ |
| การจัดวางซับซ้อนสำหรับเบราว์เซอร์เท่านั้น | เก็บ foreignObject เมื่อวิธีใช้เบราว์เซอร์นั้นตรงความต้องการ | ไฟล์ฝังหรือไฟล์อิสระที่ใช้จริง |
| ต้องการเฉพาะรูปลักษณ์ | ส่งออก PNG จากตัวเรนเดอร์ที่แสดงงานครบ | ขนาดพิกเซลและข้อความเล็กที่สุดที่ขนาดส่งมอบ |
การแปลงเป็นเส้นรอบรูปใช้ได้เฉพาะเมื่อเครื่องมือต้นทางมองเห็นและแปลงตัวอักษรได้ การเปิดไฟล์ส่งออกที่ไม่ครบอยู่แล้วและแปลงวัตถุที่เหลือไม่สามารถคืนคำที่ไม่มีในเอกสารนำเข้านั้นได้ PNG เก็บพิกเซล จึงไม่เหมาะเมื่อผู้รับต้องการข้อความที่แก้ไขได้หรือพาธเวกเตอร์สำหรับตัด
PerfectVector เหมาะตรงไหนในงานการ์ดภาพประกอบ
หากภาพประกอบของการ์ดมีเพียง PNG หรือ JPG กระบวนการแปลงคลิปอาร์ตเป็น SVG ของ PerfectVector เตรียมเวกเตอร์สำหรับประเมินให้ภาพนั้นได้ เก็บถ้อยคำเป็นองค์ประกอบข้อความแยกในโปรแกรมออกแบบ ตรวจขอบและช่องภายในภาพ เพิ่มป้าย แล้วทดสอบไฟล์ประกอบในตัวเรนเดอร์ปลายทาง
คู่มือการแปลงภาพเป็นเวกเตอร์ อธิบายว่าพิกเซลกลายเป็นพาธอย่างไร PerfectVector ไม่ได้ซ่อมป้าย HTML ใน SVG เมื่อภาพประกอบมีพาธที่ดีอยู่แล้ว ให้คงไว้และเปลี่ยนเฉพาะป้ายที่มีปัญหา ภาพหน้าจอที่ป้ายหายไม่มีตัวอักษรให้กู้ และการไล่เส้นตัวอักษรที่มองเห็นจะสร้างรูปทรง ไม่ใช่คำที่แก้ไขได้
ก่อนส่ง SVG ที่แก้แล้ว
- เปิดสำเนาส่งออกอีกครั้งในเบราว์เซอร์และปลายทางที่ตั้งใจใช้
- ยืนยันว่าทุกป้ายมองเห็น รวมถึงบรรทัดสุดท้าย
- ตรวจว่าภาพไม่เลื่อนหรือเปลี่ยนขนาด
- ตรวจฟอนต์ หรือดูตัวอักษรที่แปลงเป็นเส้นรอบรูปที่ขนาดใช้งาน
- เก็บต้นทางที่แก้ไขได้ควบคู่กับสำเนาส่งมอบ
คำถามที่พบบ่อย
ทำไมข้อความ SVG แสดงใน Chrome แต่หายเมื่อส่งออก PNG? ป้ายอาจเป็น HTML ภายใน foreignObject แต่ตัวเรนเดอร์ PNG รองรับ SVG อีกชุดย่อยหนึ่ง ตรวจมาร์กอัปของป้ายที่หาย แล้วเรนเดอร์แบบข้อความ SVG โดยตรงผ่านวิธีส่งออกเดียวกัน
เพิ่มเนมสเปซ XHTML แล้วแก้การส่งออก foreignObject ได้ทุกกรณีหรือไม่? ไม่ มันแก้เนมสเปซของเนื้อหา HTML ใน SVG อิสระ ปลายทางยังต้องรองรับเนื้อหานั้น และป้ายยังต้องมีขนาดเหมาะสมกับสไตล์ที่มองเห็นได้
tspan ตัดบรรทัดเหมือนย่อหน้า HTML ได้หรือไม่? ตัวอย่างใช้บรรทัดที่ระบุชัดและระยะเยื้องแนวตั้ง ไม่ได้จำลองการจัดย่อหน้า HTML เลือกจุดขึ้นบรรทัดให้เหมาะกับพื้นที่ และตรวจด้วยฟอนต์ปลายทาง
ควรแปลงทั้งการ์ดเป็นเวกเตอร์เพื่อกู้ป้ายหรือไม่? รักษาพาธที่มีอยู่และสร้างป้ายใหม่จากข้อความต้นฉบับ แปลงเวกเตอร์เฉพาะภาพที่เป็นพิกเซล ตัวอักษรจากการไล่เส้นเป็นเรขาคณิต จึงไม่ได้รักษาคำที่แก้ไขได้
แหล่งอ้างอิง
- MDN — foreignObject — นิยามเนื้อหาต่างเนมสเปซ แอตทริบิวต์เรขาคณิต และเนมสเปซ XHTML ใน SVG อิสระ
- MDN — tspan — อธิบายการจัดตำแหน่งส่วนต่าง ๆ ของข้อความ SVG โดยตรง
- draw.io — ปัญหาข้อความ SVG ที่ส่งออก — อธิบายการแปลงป้ายเป็น SVG ข้อจำกัดการจัดรูปแบบ และการตั้งค่าส่งออกทางเลือก
- GNOME — คุณสมบัติ SVG และ CSS ที่ Librsvg รองรับ — แสดงองค์ประกอบและแอตทริบิวต์ที่ตัวเรนเดอร์รองรับ
หากภาพประกอบยังเป็นบิตแมป เตรียมคลิปอาร์ตเป็น SVG ตรวจรูปร่าง และเพิ่มข้อความแยก ตรวจทั้งสองส่วนในไฟล์ส่งออกก่อนส่งมอบ
เพิ่มเติมจากบล็อก

ภาพ SVG ใน Graphviz: ย้ายภาพในโหนดได้ครบ
เพิ่มภาพ SVG ในโหนด Graphviz ตรวจการอ้างอิงภาพ และทดสอบชุดแอสเซ็ตครบถ้วนเทียบกับแผนภาพที่ย้ายเดี่ยวและสำเนาส่งมอบที่มีข้อมูลครบในตัว

Matplotlib SVG: เก็บกราฟและโลโก้เป็นพาธ
ส่งออกกราฟ Matplotlib เป็น SVG จัดวางพาธโลโก้แยกด้วย svgutils แล้วตรวจไฟล์ที่ส่งมอบว่ามีพิกเซลฝังอยู่หรือไม่ รวมถึงตำแหน่งและการเปลี่ยนฟอนต์