---
date: 2026-05-10
type: tooling
tags: [svg, image, npm, fallback]
---

# 没 sudo / pip / imagemagick 时用 resvg-js 渲染 SVG → PNG

## 场景

需要把 SVG 转 PNG（生成头像、文档插图、报告封面）。开发机上挨个试都没装：

```
rsvg-convert       # apt librsvg2-bin → 要 sudo
convert            # imagemagick → 要 sudo
inkscape           # 要 sudo
python3 -m pip     # 直接 No module named pip（连 ensurepip 都没）
cairosvg           # pip 装不了，且 cairo 系统库要 sudo
```

且 `sudo -n true` 也 `password required`——开发机不是 NOPASSWD（NOPASSWD 是 ffai/aixc 服务器，不是本机）。

## 解法：`@resvg/resvg-js`（npm 包）

纯 Rust binary，npm 直接装，不依赖任何系统库。FFOA 开发机有 Node + npm，立即可用。

```bash
mkdir /tmp/svgconv && cd /tmp/svgconv
npm init -y > /dev/null
npm install --silent @resvg/resvg-js     # ~5s

node -e "
const fs = require('fs');
const { Resvg } = require('@resvg/resvg-js');
const svg = fs.readFileSync('/tmp/in.svg');
const png = new Resvg(svg, {
  fitTo: { mode: 'width', value: 512 },
  font: { loadSystemFonts: true },
}).render().asPng();
fs.writeFileSync('/tmp/out.png', png);
console.log('OK', png.length, 'bytes');
"
```

## 实测

- 安装 ~5s
- 渲染 512×512 SVG with filter（gaussian blur、glow）+ gradient + text → < 100ms
- 输出 8-bit RGBA PNG，质量等同 rsvg-convert
- 系统字体自动加载（monospace/sans-serif fallback 都能识别）

## 不适用

- SVG 动画（`<animate>` 标签）→ 用 puppeteer
- 需要特定字体非系统字体 → 加 `font.fontFiles: ['/path/to/font.ttf']`
- 太复杂的 filter chain 偶尔差异 → 接受或 rsvg

## 排序

下次遇到本地 SVG→PNG 需求：

```
1. 试 resvg-js（npm install，无系统依赖，秒级）
2. 没 npm 才考虑 sudo apt install librsvg2-bin（rsvg-convert 仍是首选 binary）
3. 有 Python 但没 pip → python3 -m ensurepip 也常被禁，直接放弃
```

不要先撞 pip + cairosvg 的墙——cairo 系统库依赖会浪费 5 分钟才知道装不上。
