PerfectVector
โดย Irene Kim

โลโก้ SVG ใน Satori: เก็บภาพไว้ในการ์ดแบรนด์

ฝังโลโก้ SVG ในการ์ด Satori โดยระบุขนาดและใช้ข้อมูลภาพครบในตัว ตรวจภาพซ้อนภายใน แล้วเรนเดอร์ PNG ส่งงานแยก

อ่าน 4 นาที
ในหน้านี้

หากต้องการใส่โลโก้ SVG ในการ์ด Satori ให้ส่งเป็นต้นทางภาพ ตั้งความกว้างสูงของภาพ และเก็บ SVG ต้นฉบับข้างการ์ดที่สร้าง ในตัวอย่างด้านล่าง SVG base64 กลายเป็นภาพซ้อนภายในผล Satori ไม่ได้กลายเป็นชุดเส้นโลโก้ใหม่ที่แก้ไขได้ในตัวการ์ดชั้นนอก

Satori สร้าง SVG จาก HTML และ CSS ชุดจำกัด คำแนะนำภาพทางการ แนะนำระบุขนาดชัดเจนและใช้ข้อมูลภาพครบในตัวเมื่อมีตัวเรนเดอร์ภายหลังผลิต PNG งานนี้จึงมีผลสองแบบแยก ได้แก่ การ์ด SVG จัดองค์ประกอบและสำเนาแรสเตอร์ส่งงาน

เก็บสามไฟล์ที่มีหน้าที่ต่างกัน

ไฟล์สิ่งที่มีสิ่งที่แก้ที่นั่น
SVG โลโก้ต้นฉบับรูปทรงและช่องตรารูป สี ขอบเขตต้นทาง
SVG การ์ด Satoriเค้าโครง ตัวอักษร และภาพโลโก้ฝังกรอบภาพ ตำแหน่ง และเนื้อหาการ์ด
PNG เรนเดอร์พิกเซลการ์ดที่ส่งสร้างใหม่หลังเปลี่ยนต้นฉบับ

<image> ใน SVG อ้างถึง SVG อีกไฟล์ได้ ตามเอกสาร image ของ MDN องค์ประกอบภาพจึงไม่ได้หมายความว่าภาพฝังเป็นแรสเตอร์โดยอัตโนมัติ ตรวจชนิดข้อมูลและเนื้อหาที่ถอดรหัสก่อนวินิจฉัยการ์ดด้วยรายการตรวจภาพแรสเตอร์ใน SVG ฉบับกว้าง

เก็บต้นฉบับข้างการ์ด
ภาพแนวคิดของต้นฉบับข้าวหลามตัดโปร่งกลางและสำเนาวางต่างขนาดในการ์ดแบรนด์เรียบง่าย
ภาพอธิบาย: เก็บงานที่แก้ไขได้แยกจากการจัดการ์ด การตรวจต้นฉบับและผลด้านล่างมาจากตัวอย่าง Satori ที่สร้างแยก ไม่ใช่แผนภาพที่สร้างนี้

ตัวอย่างในเครื่องครบชุด

โค้ดเริ่มต้นนี้ใช้ import มาตรฐานที่ให้ผล SVG จาก Satori 0.35.0 กับ resvg-js 2.6.2 ในโฟลเดอร์งานว่าง ให้ติดตั้งแพ็กเกจตรึงรุ่น:

npm install --save-exact satori@0.35.0 @resvg/resvg-js@2.6.2

สร้างโฟลเดอร์ fonts และดาวน์โหลด Abel-Regular.ttf กับ OFL.txt จากไดเรกทอรี Abel ของ Google Fonts Abel อยู่ภายใต้ SIL Open Font License 1.1 เก็บประกาศและใบอนุญาตที่มาด้วยเมื่อแจกฟอนต์พร้อมตัวอย่างนี้

บันทึกโค้ดต่อไปเป็น starter.mjs แล้วรัน node starter.mjs มันส่งฟอนต์ให้ Satori สร้างรูปข้าวหลามตัดโปร่งกลาง และทำการ์ด 600×320 สองใบที่กรอบภาพ 80×80 กับ 160×160 URL ไฟล์คงพาธฟอนต์และผลลัพธ์สัมพันธ์กับสคริปต์

import { readFile, writeFile } from 'node:fs/promises';
import satori from 'satori';
import { Resvg } from '@resvg/resvg-js';
 
const logo = `<svg xmlns="http://www.w3.org/2000/svg" width="128" height="128" viewBox="0 0 128 128"><path d="M64 8 L120 64 L64 120 L8 64 Z M64 42 L86 64 L64 86 L42 64 Z" fill="#176b5b" fill-rule="evenodd"/></svg>`;
const src = `data:image/svg+xml;base64,${Buffer.from(logo).toString('base64')}`;
const font = await readFile(new URL('./fonts/Abel-Regular.ttf', import.meta.url));
await writeFile(new URL('./logo-master.svg', import.meta.url), logo);
 
for (const size of [80, 160]) {
  const svg = await satori({
    type: 'div',
    props: {
      style: { display: 'flex', width: 600, height: 320,
        backgroundColor: '#f6f2e8', color: '#152e29', fontFamily: 'Abel' },
      children: [
        { type: 'img', props: { src, width: size, height: size,
          style: { position: 'absolute', left: 24, top: 64 } } },
        { type: 'div', props: {
          style: { position: 'absolute', left: 220, top: 112, fontSize: 42 },
          children: 'CEDAR FIELD' } },
        { type: 'div', props: {
          style: { position: 'absolute', left: 220, top: 168, fontSize: 20 },
          children: 'A study in simple shapes' } },
      ],
    },
  }, {
    width: 600, height: 320,
    fonts: [{ name: 'Abel', data: font, weight: 400, style: 'normal' }],
  });
  const png = new Resvg(svg, { font: { loadSystemFonts: false } }).render().asPng();
  await writeFile(new URL(`./card-${size}.svg`, import.meta.url), svg);
  await writeFile(new URL(`./card-${size}.png`, import.meta.url), png);
}

Buffer.from(logo).toString('base64') เข้ารหัสไบต์ SVG UTF-8 ที่สร้างโดยใช้API เข้ารหัส Buffer ของ Node คำนำ data:image/svg+xml;base64, ระบุเนื้อหา มันเปลี่ยนรูปแบบขนส่ง ไม่ใช่รูปทรงโลโก้

การเรียก Satori คืน SVG การ์ด บรรทัดถัดไปส่ง SVG นั้นให้ตัวเรนเดอร์ PNG resvg-js แยก โค้ดเริ่มต้นไม่มี URL ภาพระยะไกล แต่อ่านฟอนต์ในเครื่องก่อนเรนเดอร์ ทดสอบการดึงข้อมูลระยะไกลหรือการนำขึ้นใช้งานของคุณแยก

ผลจากการเรียกจริงสองครั้ง

เรารันโค้ดเริ่มต้นนี้ตรง ๆ ด้วยแพ็กเกจที่ตรึง ตรวจ SVG ผลลัพธ์ทั้งสอง และเปิด SVG กับ PNG แต่ละชุดในเบราว์เซอร์ ไฟล์การ์ดทั้งสี่โหลดที่ 600×320 ตัวอักษรอยู่ตำแหน่งเดิมขณะที่กรอบตราใหญ่สองเท่า

การ์ดแต่ละใบมี <image> ชั้นนอกหนึ่งตัวและ <path> ชั้นนอกสองตัว สองเส้นแทนตัวอักษร ไม่ใช่เส้นขอบนอกและในของรูปข้าวหลามตัด การถอด base64 ของภาพกู้ไบต์ SVG ต้นฉบับตรงกัน ได้แก่ หนึ่งเส้น ไม่มีองค์ประกอบภาพ และนิยามรูปโปร่งกลางเดิม การ์ดไม่มีองค์ประกอบ <text> ที่ยังเป็นข้อความในการรันนี้

การตรวจกรอบภาพ 80×80กรอบภาพ 160×160
ขนาดการ์ด600×320600×320
ตำแหน่งภาพชั้นนอกx24, y64x24, y64
SVG ฝังต้นฉบับ 128×128ไบต์ต้นฉบับเดิม
ขอบเขต PNG สีเขียวน้ำทะเลทึบตรงค่า68×68 พิกเซล138×138 พิกเซล
พิกเซลการ์ดที่กลางช่องครีม อัลฟา 255ครีม อัลฟา 255

แถวขอบเขตระบายสีนับพิกเซลที่ตรงสีเขียวน้ำทะเลทึบของตราแบบแน่นอน ไม่รวมขอบลบรอยหยัก ไม่ใช่ขนาดกรอบภาพ เพราะรูปต้นฉบับครอบคลุมพิกัด 8 ถึง 120 ขอบเขตคณิตศาสตร์จึงปรับเป็น 70 หรือ 140 หน่วยภายในกรอบเหล่านี้ ขอบเขตสีทึบที่วัดเล็กกว่าเล็กน้อย

กลางตราต้นฉบับโปร่งใสด้วยอัลฟา 0 เมื่อเรนเดอร์เดี่ยว ใน PNG การ์ดสุดท้ายแต่ละไฟล์ ช่องนั้นแสดงพื้นครีมทึบ RGBA 246,242,232,255 ช่องที่เห็นกับพิกเซลการ์ดสุดท้ายโปร่งใสเป็นข้อกำหนดต่างกัน หากต้องการพื้นส่งงานโปร่งใส ให้เปลี่ยนพื้นการ์ดและตรวจอัลฟาที่ได้แยก

นี่คือสองการเรียกที่ใช้ตราต้นฉบับเดียวสองขนาด ไม่ยืนยันว่าทุกคุณสมบัติ SVG ใช้ได้ งานภาพระยะไกลซ้ำ ๆ ถูกแก้แล้ว หรือทุกปลายทางเรนเดอร์การ์ดเหมือนกัน

เปลี่ยนกรอบภาพโดยไม่สูญต้นฉบับ

สำหรับโลโก้ของคุณ แทนสตริง logo ด้วย SVG ครบในตัว หรืออ่านไฟล์ต้นฉบับก่อนเข้ารหัส ตรวจ viewBox ความกว้างสูงและช่องก่อน พื้นที่ว่างส่วนเกินในขอบเขตอาจทำให้โลโก้ที่เห็นเล็กกว่ากรอบที่กำหนดในการ์ด

ตั้งทั้งสองมิติของภาพให้ตรงสัดส่วนเป้าหมาย ต้นฉบับและกรอบทั้งสองของเราเป็นจัตุรัส ภาพส่งออกใช้ preserveAspectRatio="none" ซึ่งไม่เปลี่ยนสัดส่วนที่นี่ ไฟล์ทดสอบนี้ไม่ได้ทดสอบโลโก้สี่เหลี่ยมผืนผ้าที่บังคับเข้าช่องจัตุรัส เปลี่ยนตัวแปรเค้าโครงทีละค่า แล้วตรวจ SVG จริงกับ PNG ส่งงาน

เก็บตัวอักษรนอกโลโก้ฝังเมื่อต้องการเปลี่ยนแยก ข้อความการ์ดในตัวอย่างกลายเป็นเส้นใน SVG ที่ส่ง แต่คำยังแก้ได้ในสคริปต์ อินพุตฟอนต์ อินพุตภาพ และผลจัดองค์ประกอบมีหน้าที่ต่างกัน คู่มือฟอนต์ resvg ครอบคลุมอีกขั้นตอนเรนเดอร์ข้อความ SVG ที่ยังเป็นข้อความ

เอกสาร HTML และ CSS ของ Satori อธิบายชุดที่รองรับและข้อจำกัด ภาพหน้าจอหน้าเดิมในเบราว์เซอร์ไม่ได้รับปากว่าเอนจินเค้าโครงนี้จะทำซ้ำตรงทุกจุด เริ่มการ์ดเล็กและ import satori ปกติ แล้วเพิ่มคุณสมบัติที่การออกแบบต้องใช้จริง

เตรียมโลโก้ที่เริ่มจากพิกเซล

หากโลโก้เดียวเป็น PNG หรือ JPG และต้องการเส้นแก้ไขได้ ให้เตรียมโลโก้ SVG ด้วย PerfectVector ตรวจเงารูปร่างกับช่องใน และเก็บ SVG สะอาดเป็นต้นฉบับหลัก จากนั้นฝังในการ์ดและยืนยันทั้งสองขนาดภาพกับ PNG สุดท้าย การแปลงเวกเตอร์เตรียมภาพ ส่วน Satori จัดการ์ด SVG สะอาดเดิมไปขั้นฝังได้โดยตรง คู่มือแปลงเวกเตอร์ อธิบายความต่างต้นฉบับกับผล

เก็บต้นฉบับ สคริปต์ และฟอนต์อินพุตหลังส่ง PNG หากใช้ขั้นแรสเตอร์อื่น ให้ตรวจขนาดแยก ตัวอย่าง SVG เป็น PNG ด้วย Sharp ครอบคลุมขนาดของตัวเรนเดอร์นั้น

คำถามที่พบบ่อย

ภาพ SVG กลายเป็นเส้นแก้ไขได้ในการ์ด Satori หรือไม่? ในตัวอย่างนี้ โลโก้ยังเป็นภาพ SVG ซ้อนภายใน ต้นฉบับหนึ่งเส้นเดิมเก็บในข้อมูลภาพ เส้นการ์ดชั้นนอกเป็นตัวอักษร เก็บต้นฉบับสำหรับแก้รูปทรง

ทำไมโลโก้ที่เห็นเล็กกว่าความกว้างสูง? กรอบภาพรวมขอบเขตต้นฉบับ รูปข้าวหลามตัดของเราเว้นขอบในต้นฉบับ 128×128 และการวัดพิกเซลสีตรงก็ไม่รวมขอบลบรอยหยัก ตรวจพื้นที่ว่างต้นฉบับและสัดส่วนที่กำหนดแยก

ช่องโปร่งใสโลโก้ทำให้การ์ดโปร่งใสหรือไม่? ช่องให้พื้นการ์ดแสดงผ่าน พื้นครีมของเราทึบ พิกเซล PNG ในช่องจึงมีอัลฟา 255 ทดสอบพื้นการ์ดโปร่งใสแยกหากการส่งต้องใช้

Satori คืน PNG หรือไม่? โค้ดเริ่มต้นขอสตริง SVG จาก Satori แล้วเรนเดอร์เป็น PNG ด้วย resvg-js เก็บขั้นแยกเพื่อให้ตรวจเค้าโครงและผลแรสเตอร์ได้อิสระ

แหล่งข้อมูล

  1. เอกสารภาพ เค้าโครง และฟอนต์ Satori — ขนาดภาพ อินพุตครบในตัว ผล SVG มาตรฐาน และขอบเขต HTML/CSS ที่รองรับ
  2. รุ่น Satori 0.35.0 — รุ่นตรึงที่ใช้ในตัวอย่างต้นฉบับ
  3. องค์ประกอบ image ของ SVG — ภาพ SVG อ้างถึงไฟล์ SVG อื่นได้
  4. API เข้ารหัส Buffer ของ Node — การเข้ารหัส base64 ในตัวอย่าง
  5. การใช้ resvg-js — ขั้นเรนเดอร์ SVG เป็น PNG แยก
  6. ใบอนุญาตฟอนต์ Abel — ที่มา ประกาศ และใบอนุญาตแจกต่อของฟอนต์

สำหรับโลโก้ PNG หรือ JPG ของคุณ ให้เตรียมต้นฉบับ SVG ด้วย PerfectVector และตรวจเส้นขอบกับช่องใน เก็บต้นฉบับแล้วตรวจการวางในการ์ด SVG กับ PNG ที่ส่งตามขนาดที่ตั้งใจใช้

เพิ่มเติมจากบล็อก

PerfectVector

เริ่มต้นด้วย SVG ที่เรียบร้อยขึ้น
และแก้ไขได้ง่ายกว่า

ไม่ต้องใช้บัตรเครดิต