Satori SVG 로고: 브랜드 카드에 그림 넣기
명시적인 치수와 자체 완결형 이미지 데이터로 Satori 카드에 SVG 로고를 넣으세요. 중첩된 그림을 확인한 뒤 별도의 전달용 PNG를 렌더링합니다.
Satori 카드에 SVG 로고를 넣으려면 이미지 소스로 전달하고 이미지 너비와 높이를 설정한 다음, 생성된 카드와 함께 원본 SVG를 보관하세요. 아래 예제에서는 base64 SVG가 Satori 출력의 중첩 이미지가 됩니다. 바깥 카드에서 로고를 편집할 수 있는 새로운 경로 집합으로 바뀌지는 않습니다.
Satori는 제한된 HTML과 CSS로 SVG를 만듭니다. 공식 이미지 안내는 이후 렌더러에서 PNG를 만들 경우 치수를 명시하고 자체 완결형 이미지 데이터를 사용하도록 권장합니다. 따라서 이 작업에는 합성된 SVG 카드와 전달용 래스터 사본이라는 별도 출력 두 개가 있습니다.
역할이 다른 파일 세 개 보관하기
| 파일 | 들어 있는 것 | 해당 파일에서 바꿀 것 |
|---|---|---|
| 원본 로고 SVG | 엠블럼의 도형과 구멍 | 모양, 색, 원본 경계 |
| Satori 카드 SVG | 카드 배치, 글자, 내장 로고 이미지 | 그림 상자, 위치, 카드 내용 |
| 렌더링한 PNG | 전달할 카드의 픽셀 | 원본 변경 후 다시 생성 |
MDN image 참고 문서에 설명된 것처럼 SVG <image>는 다른 SVG를 참조할 수 있습니다. 따라서 이미지 요소가 있다고 내장 그림이 자동으로 래스터인 것은 아닙니다. 더 넓은 범위의 SVG 래스터 이미지 점검표로 카드를 진단하기 전에 데이터 유형과 디코딩한 내용을 확인하세요.

완전한 로컬 예제
이 시작 예제는 Satori 0.35.0의 표준 SVG 출력 가져오기와 resvg-js 2.6.2를 사용합니다. 빈 작업 폴더에서 버전을 고정한 패키지를 설치하세요.
npm install --save-exact satori@0.35.0 @resvg/resvg-js@2.6.2fonts 폴더를 만들고 Google Fonts Abel 디렉터리에서 Abel-Regular.ttf와 OFL.txt를 다운로드하세요. Abel은 SIL Open Font License 1.1 라이선스를 따릅니다. 이 예제와 함께 글꼴을 배포할 때 동봉된 고지와 라이선스를 유지하세요.
다음을 starter.mjs로 저장하고 node starter.mjs를 실행하세요. Satori에 글꼴을 제공하고 속이 빈 마름모를 작성한 다음, 그림 상자가 각각 80×80과 160×160인 600×320 카드 두 개를 만듭니다. 파일 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')는 Node의 Buffer 인코딩 API로 작성한 UTF-8 SVG 바이트를 인코딩합니다. data:image/svg+xml;base64, 접두사가 콘텐츠를 식별합니다. 전송 표현을 바꾸는 것이며 로고의 도형을 바꾸는 것은 아닙니다.
Satori 호출은 카드 SVG를 반환합니다. 다음 줄에서는 그 SVG를 별도의 resvg-js PNG 렌더러에 전달합니다. 이 시작 예제에는 원격 이미지 URL이 없으며 렌더링 전에 로컬 글꼴을 읽습니다. 원격 가져오기나 배포 환경의 동작은 별도로 시험하세요.
실제 호출 두 번에서 나온 결과
고정 버전 패키지로 이 시작 예제를 그대로 실행하고, 출력 SVG 두 개를 점검한 뒤 각 SVG와 PNG를 브라우저에서 열었습니다. 카드 파일 네 개 모두 600×320으로 로드됐습니다. 글자는 같은 위치에 있고 엠블럼 상자의 크기는 두 배가 됐습니다.
각 카드에는 바깥쪽 <image> 하나와 바깥쪽 <path> 요소 두 개가 있었습니다. 경로 두 개는 글자를 나타내며 마름모의 바깥·안쪽 윤곽이 아닙니다. 이미지의 base64 데이터를 디코딩하자 원본 SVG 바이트가 정확히 복원됐습니다. 경로 하나, 이미지 요소 0개, 동일한 속 빈 마름모 정의였습니다. 이번 실행에서 카드에는 편집 가능한 <text> 요소가 없었습니다.
| 점검 항목 | 80×80 그림 상자 | 160×160 그림 상자 |
|---|---|---|
| 카드 치수 | 600×320 | 600×320 |
| 바깥 이미지 위치 | x24, y64 | x24, 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의 텍스트 요소를 렌더링하는 별도의 작업 과정을 다룹니다.
Satori의 HTML 및 CSS 문서는 지원하는 하위 집합과 한계를 설명합니다. 기존 페이지의 브라우저 화면 캡처가 이 레이아웃 엔진에서 정확하게 재현된다는 보장은 아닙니다. 작은 카드와 일반 satori 가져오기로 시작한 다음 디자인에 실제로 필요한 속성을 추가하세요.
픽셀로만 있는 로고 준비하기
유일한 로고가 PNG나 JPG이고 편집 가능한 윤곽이 필요하다면 PerfectVector로 SVG 로고를 준비하고 실루엣과 안쪽 구멍을 확인한 뒤 깔끔한 SVG를 원본으로 보관하세요. 그다음 카드에 넣어 두 그림 크기와 최종 PNG를 확인합니다. 벡터화는 그림을 준비하고 Satori는 카드 구성을 처리합니다. 이미 깔끔한 SVG가 있다면 바로 삽입 단계로 넘어갈 수 있습니다. 벡터화 가이드는 원본과 출력의 차이를 설명합니다.
PNG를 전달한 뒤에도 원본, 스크립트, 글꼴 입력을 보관하세요. 다른 래스터화 단계를 사용한다면 해당 단계의 크기 처리를 별도로 확인합니다. Sharp SVG-PNG 예제는 그 렌더러의 치수를 다룹니다.
자주 묻는 질문
Satori 카드에서 SVG 이미지가 편집 가능한 경로로 바뀌나요? 이 예제에서는 로고가 중첩된 SVG 이미지로 남습니다. 원래의 단일 경로 원본은 이미지 데이터 안에 보존되고, 카드 바깥쪽 경로는 글자입니다. 도형 편집을 위해 원본 파일을 보관하세요.
눈에 보이는 로고가 너비와 높이보다 작은 이유는 무엇인가요? 이미지 상자는 원본 경계를 포함합니다. 이 마름모는 128×128 원본 안에 여백을 남기며, 정확한 색상의 픽셀 경계에서는 안티앨리어싱된 가장자리도 제외됩니다. 원본 여백과 지정한 가로세로 비율을 따로 확인하세요.
로고의 투명한 구멍 때문에 카드도 투명해지나요? 구멍은 카드 배경이 보이게 합니다. 이 예제의 크림색 배경은 불투명하므로 구멍 위치의 PNG 픽셀 알파는 255입니다. 전달 요건에 필요하다면 투명한 카드 배경을 별도로 시험하세요.
Satori가 PNG를 반환하나요? 이 시작 예제는 Satori에 SVG 문자열을 요청한 다음 resvg-js로 해당 문자열을 PNG로 렌더링합니다. 레이아웃과 전달용 래스터를 독립적으로 확인할 수 있도록 두 단계를 분리하세요.
출처
- Satori 이미지, 레이아웃, 글꼴 문서 — 이미지 치수, 자체 완결형 입력, 표준 SVG 출력, 지원하는 HTML/CSS 범위입니다.
- Satori 0.35.0 릴리스 — 직접 작성한 예제에 사용한 고정 버전입니다.
- SVG image 요소 — SVG 이미지는 다른 SVG 파일을 참조할 수 있습니다.
- Node Buffer 인코딩 API — 시작 예제의 base64 인코딩 작업입니다.
- resvg-js 사용법 — 별도의 SVG-PNG 렌더링 단계입니다.
- Abel 글꼴 라이선스 — 글꼴의 출처, 고지, 재배포 라이선스입니다.
자신의 PNG나 JPG 로고라면 PerfectVector로 SVG 원본을 준비하고 윤곽과 안쪽 구멍을 확인하세요. 원본을 보관한 뒤, 의도한 사용 크기에서 카드 SVG와 전달용 PNG의 로고 배치를 확인합니다.


