resvg SVG 글꼴: 그림에 필요한 글꼴 불러오기
명시적인 글꼴 파일로 resvg에서 누락되거나 대체된 SVG 텍스트를 해결하세요. 작은 Node 예제를 실행하고 세 출력을 비교하며 편집 가능한 그림 원본을 보존합니다.
목차
resvg에서 SVG 글꼴을 안정적으로 렌더링하려면 렌더러에 글꼴 파일을 제공하고 SVG에서 해당 패밀리 이름을 사용하세요. 네이티브 Node 바인딩 @resvg/resvg-js에서는 fontFiles를 설정합니다. 작업이 받는 글꼴만 정확히 테스트하려면 loadSystemFonts: false로 설정하세요. 프로젝트의 Node 예제가 이 구성을 보여 줍니다.
잘못된 글꼴을 써도 PNG는 완전해 보일 수 있습니다. 내보내기 명령이 성공해도 글자 모양을 확인하세요.
글꼴 입력 세 가지, SVG 하나
경로로 작은 산 문양을 만들고 옆에 편집 가능한 텍스트 PINE & FIELD를 배치했습니다. SVG는 일반 굵기의 Abel 패밀리를 요청합니다. @resvg/resvg-js 2.6.2, Node 22.19.0과 macOS arm64로 같은 원본을 세 번 렌더링했습니다. 모든 경우 시스템 글꼴 탐색을 껐습니다.
| 제공한 글꼴 파일 | 관찰 결과 |
|---|---|
| 없음 | 경로 문양은 렌더링됐지만 레이블은 사라짐 |
| Anton만 제공 | 레이블이 눈에 띄게 다른 더 굵은 글꼴로 렌더링됨 |
| Abel | 의도한 가는 글자가 렌더링됨 |

이 관찰은 해당 예제와 구성에 대한 것입니다. 다른 글꼴 모음, 바인딩이나 버전이 어떤 대체 글꼴을 고를지 확정하지는 않습니다. 유용한 진단은 더 단순합니다. 요청한 패밀리가 없으면 텍스트가 사라지거나 대체 글꼴로 그럴듯하게 렌더링될 수 있습니다.
resvg-js에서 로컬 글꼴 불러오기
이 예제는 별도 WebAssembly 패키지가 아니라 네이티브 Node 패키지를 사용합니다. 바인딩의 버전별 타입 정의는 font 옵션 아래 fontFiles, fontDirs, loadSystemFonts를 나열합니다.
새 작업 폴더에 여기서 사용한 버전을 설치하세요.
npm install --save-exact @resvg/resvg-js@2.6.2Google Fonts Abel 디렉터리에서 Abel-Regular.ttf와 함께 제공되는 OFL.txt를 다운로드하세요. 둘 다 fonts 하위 폴더에 보관하세요. Abel은 SIL Open Font License로 제공되므로 예제를 배포할 때 글꼴과 라이선스를 함께 유지하세요.
다음을 label.svg로 저장하세요.
<svg xmlns="http://www.w3.org/2000/svg"
width="880" height="240" viewBox="0 0 880 240">
<rect width="880" height="240" fill="#f6f2e8"/>
<path d="M46 155 L96 57 L147 155 Z" fill="#176b5b"/>
<path d="M75 155 L112 88 L166 155 Z" fill="#81ab78"/>
<text x="195" y="151" font-family="Abel"
font-size="82" font-weight="400" fill="#152e29">
PINE & FIELD
</text>
</svg>그런 다음 SVG 옆에 render.mjs를 저장하세요.
import { access, readFile, writeFile } from 'node:fs/promises';
import { fileURLToPath } from 'node:url';
import { Resvg } from '@resvg/resvg-js';
const fontFile = fileURLToPath(
new URL('./fonts/Abel-Regular.ttf', import.meta.url)
);
await access(fontFile);
const svg = await readFile(new URL('./label.svg', import.meta.url));
const renderer = new Resvg(svg, {
font: {
loadSystemFonts: false,
fontFiles: [fontFile],
},
});
const png = renderer.render().asPng();
await writeFile(new URL('./label.png', import.meta.url), png);node render.mjs를 실행하세요. 파일 URL은 입력·출력 경로를 스크립트 기준으로 만들므로 터미널 작업 디렉터리를 바꿔도 여는 글꼴이 달라지지 않습니다. access()는 글꼴이 없거나 접근 불가하면 직접적인 파일시스템 오류를 제공하며 글꼴 내용은 검증하지 않습니다.
대조 결과를 재현하려면 SVG는 그대로 두세요. 첫 행에는 빈 fontFiles 배열을 사용하세요. 두 번째는 Google Fonts Anton 디렉터리에서 Anton-Regular.ttf를 다운로드하고 라이선스를 보관한 뒤 Abel 대신 제공하세요. 다른 것을 바꾸기 전에 각 PNG를 확인하세요.
파일명이 아닌 패밀리 이름 맞추기
Abel-Regular.ttf는 파일 경로입니다. Abel은 SVG가 요청하는 패밀리입니다. font-family="Abel-Regular.ttf"를 써도 렌더러에게 그 파일을 열라고 지시하지는 않습니다.
SVG font-family 속성은 패밀리 이름이나 일반 패밀리를 받으며 여러 개를 지정하면 우선순위 목록이 됩니다. CSS 대응 속성도 있습니다. 적용되는 CSS font-family 선언은 표현 속성보다 우선합니다.
자신의 그림에서는 세 가지를 함께 확인하세요.
- 패밀리: 글꼴 내부에 기록되고 SVG에서 요청하는 이름입니다.
- 스타일과 굵기: 제공한 글꼴이 의도한 글자와 맞는지 확인하세요.
- 문자: 실제 레이블의 글자와 기호를 글꼴이 포함하는지 확인하세요.
readFile 성공은 바이트를 읽었다는 사실만 증명합니다. 단어가 보인다는 것은 어떤 글자가 렌더링됐다는 사실만 증명합니다. 어느 쪽도 디자인의 글꼴을 선택했다는 증거가 아닙니다.
편집 가능 텍스트와 윤곽선의 더 넓은 진단은 내보내기 후 SVG 글꼴이 바뀌는 이유를 참고하세요.
내보내기 환경에서 같은 입력 확인하기
글꼴을 그림 작업의 입력으로 취급하세요. 배포나 작업 묶음에 필요한 글꼴 파일을 포함하고 그곳에서 해석한 경로가 해당 파일을 가리키는지 확인하세요. 서버 작업을 구성할 때 디자인 노트북에 설치된 글꼴은 놓치기 쉽습니다.
시스템 탐색을 끄고 테스트 레이블을 지원하는 가장 작은 명시적 글꼴 목록으로 시작하세요. 출력이 올바르면 그림에서 쓰는 실제 문구, 문장부호, 굵기와 언어를 테스트하세요. 일반 굵기 라틴 레이블은 다른 문자 체계나 복잡한 글꼴 패밀리를 테스트하지 않습니다.
글자가 여전히 잘못 보이면 소스에서 CSS 재정의와 중첩 <tspan> 스타일을 확인하세요. 문양과 레이블 모두 예상치 않게 잘리거나 크기가 바뀌면 SVG 경계와 래스터 크기를 별도로 조사하세요. CairoSVG 크기 안내는 다른 렌더러에서 그 차이를 다루며 옵션은 CairoSVG 전용입니다.
버그 보고나 재현 가능한 내보내기 작업을 공유할 때 SVG, 정확한 바인딩 버전, 글꼴 파일명과 버전, 렌더러 옵션과 예상 이미지를 포함하세요. 파일을 패키징할 때 글꼴 재배포 허용 여부도 고려하세요.
PNG 옆에 편집 가능한 소스 보관하기
위 코드는 PNG를 작성합니다. 래스터 전달 파일이며 보이는 글자는 더 이상 편집 가능한 SVG 텍스트가 아닙니다. 이후 문구 변경을 위해 label.svg와 글꼴 입력을 소스로 보관하세요.
수신자에게 고정 글자의 벡터 로고가 필요하면 벡터 편집기에서 별도의 윤곽선 SVG 전달 사본을 준비하고 확인하세요. 편집 가능한 텍스트 원본을 유지하세요. 로고 파일 형식 가이드는 서로 다른 역할을 하는 소스·전달 파일을 설명합니다.
필요한 문양이 PNG나 JPG에만 있다면 PerfectVector 로고 벡터화 도구가 디자인의 해당 부분에 벡터 그림을 복원하는 데 도움이 됩니다. 결과 경로를 확인하고 원하지 않는 추적 글자를 제거한 뒤 알려진 글꼴로 레이블을 다시 입력하고 resvg 내보내기를 실행하세요. 벡터화는 원래 글꼴을 알아내거나 편집 가능한 텍스트를 복원하지 않습니다. 이미지 벡터화 가이드는 변환에서 무엇이 바뀌는지 설명합니다.
FAQ
시스템 글꼴을 끄면 텍스트가 사라지는 이유는 무엇인가요? 빈 글꼴 테스트에서는 편집 가능한 레이블에 사용할 글꼴을 제공하지 않아 경로 그림만 표시됐습니다. 적합한 글꼴을 명시적으로 불러오고 패밀리, 스타일과 문자 지원을 확인하세요.
글꼴 파일명을 SVG 패밀리 이름으로 써도 되나요? SVG에는 글꼴의 패밀리 이름을 쓰세요. 로컬 파일명은 fontFiles로 별도 전달하세요. 글꼴 파일명을 바꿔도 내부 패밀리 이름이 바뀌지는 않습니다.
resvg가 PNG 로고를 편집 가능한 SVG로 바꾸나요? 이 예제는 SVG를 PNG로 렌더링하며 래스터 로고를 벡터화하지 않습니다. 필요하다면 벡터화 작업으로 문양을 복원하고 편집 가능한 텍스트를 추가한 뒤 그 SVG를 원본으로 유지하세요.
Sources
- resvg-js — 버전 2.6.2 README — 네이티브 Node 사용과 명시적 글꼴 로딩을 설명합니다.
- resvg-js — 버전 2.6.2 타입 정의 — 글꼴 설정과 렌더링 이미지 API를 설명합니다.
- MDN — SVG font-family — 패밀리 목록과 CSS 우선순위를 설명합니다.
- Google Fonts — Abel — 의도한 레이블에 사용한 일반 글꼴과 라이선스입니다.
- Google Fonts — Anton — 대체 글꼴 대조에 사용한 글꼴과 라이선스입니다.
래스터 문양 때문에 작업이 지연된다면 로고 그림을 벡터화하고 편집기에서 가장자리를 확인한 뒤 편집 가능한 텍스트로 레이블을 추가하세요. 글꼴 파일을 명시해 렌더링하고 전달 전에 PNG와 원본을 비교하세요.

