如何将 SVG 转换为 PNG(浏览器、命令行和代码)
SVG 是矢量格式——可以完美缩放到任意尺寸。PNG 是栅格格式——像素固定,但大多数应用、邮件客户端和社交网络只接受它。转换听起来简单,但有几个重要选择:以什么分辨率导出、如何处理透明度,以及外部字体怎么办。
在浏览器中
将 SVG 文件拖入或粘贴到转换器中,设置目标宽度,下载 PNG。该工具使用浏览器自己的引擎渲染 SVG——和你在网页中查看 SVG 时的渲染路径一样——然后导出到 PNG 画布。
这是一次性转换最快的选项,能正确处理绝大多数实际场景中的 SVG。
命令行:Inkscape
Inkscape 是浏览器之外最准确的 SVG 渲染器——使用相同的渲染引擎(cairo),能正确处理滤镜、遮罩和路径文字等 SVG 特性。
# 安装
brew install inkscape # macOS
sudo apt install inkscape # Ubuntu
# 以 96 DPI(默认屏幕分辨率)转换为 PNG
inkscape input.svg --export-filename=output.png
# 导出为指定像素宽度
inkscape input.svg --export-filename=output.png --export-width=512
# 导出为 2×(高 DPI / 视网膜屏)
inkscape input.svg --export-filename=output.png --export-width=512 --export-dpi=192
# 导出指定区域(SVG 单位中的 x:y:宽:高)
inkscape input.svg --export-filename=output.png --export-area=0:0:100:100
无头服务器上加 --export-type=png:
inkscape input.svg --export-type=png --export-filename=output.png --export-width=1024
命令行:ImageMagick
ImageMagick 的 SVG 支持底层依赖 librsvg 或 Inkscape(取决于安装方式),批量处理时很方便。
# 安装
brew install imagemagick # macOS
sudo apt install imagemagick # Ubuntu
# 基本转换
convert input.svg output.png
# 以指定密度转换(越高 = 输出越大)
convert -density 150 input.svg output.png
# 调整到指定宽度
convert input.svg -resize 512x output.png
# 批量转换文件夹中所有 SVG
for f in *.svg; do convert "$f" "${f%.svg}.png"; done
注意: ImageMagick 的内置 SVG 渲染器较为基础,复杂 SVG(滤镜、渐变、遮罩)可能渲染不正确。对于复杂文件,通过 Inkscape 处理:
inkscape "$f" --export-filename="${f%.svg}.png" --export-width=512
命令行:rsvg-convert(librsvg)
rsvg-convert 轻量且快速,适合不含复杂滤镜的简单 SVG。
# 安装
brew install librsvg # macOS
sudo apt install librsvg2-bin # Ubuntu
# 以 96 DPI 转换
rsvg-convert input.svg -o output.png
# 以 2× 分辨率转换(192 DPI 用于视网膜屏)
rsvg-convert -d 192 -p 192 input.svg -o output.png
# 转换为指定宽度
rsvg-convert -w 512 input.svg -o output.png
Node.js:sharp
sharp 可以使用 libvips 将 SVG 光栅化。
npm install sharp
const sharp = require('sharp');
// 将 SVG 转换为 512px 宽的 PNG
sharp('input.svg')
.resize(512)
.png()
.toFile('output.png')
.then(info => console.log(`输出:${info.width}×${info.height}`));
批量生成多种尺寸:
const sharp = require('sharp');
const fs = require('fs');
const path = require('path');
const inputDir = './icons/svg';
const outputDir = './icons/png';
fs.readdirSync(inputDir)
.filter(f => f.endsWith('.svg'))
.forEach(file => {
const name = path.basename(file, '.svg');
for (const size of [16, 32, 64, 128, 256, 512]) {
sharp(path.join(inputDir, file))
.resize(size)
.png()
.toFile(path.join(outputDir, `${name}-${size}.png`));
}
});
Python:cairosvg
cairosvg 使用与 Inkscape 相同的 cairo 渲染引擎。
pip install cairosvg
import cairosvg
# 以默认分辨率转换为 PNG
cairosvg.svg2png(url='input.svg', write_to='output.png')
# 转换为指定宽度
cairosvg.svg2png(url='input.svg', write_to='output.png', output_width=512)
# 从字符串转换
svg_content = open('input.svg').read()
cairosvg.svg2png(bytestring=svg_content.encode(), write_to='output.png', output_width=512)
分辨率指南
SVG 与分辨率无关。导出为 PNG 时必须选择像素尺寸:
| 使用场景 | 推荐宽度 |
|---|---|
| Favicon(浏览器标签页) | 32 px、64 px |
| 应用图标(iOS、Android) | 512 px(再缩小) |
| 社交媒体头像 | 400 px |
| 网站高 DPI Logo | CSS 显示尺寸的 2× |
| 打印 | 300 DPI × 英寸宽度 |
网站使用时,导出为 CSS 显示尺寸的 2×,并通过 srcset 配合 2x 描述符提供。
处理透明度
SVG 原生支持透明度。PNG 支持完整的 alpha 通道。转换会保留透明度——只要 SVG 没有显式的背景矩形,你就能得到透明背景的 PNG,而不是白色背景。
如果需要白色背景:
# ImageMagick:转换前平铺到白色
convert -background white -alpha remove input.svg output.png
// sharp:用白色背景平铺
sharp('input.svg')
.flatten({ background: { r: 255, g: 255, b: 255 } })
.png()
.toFile('output-white-bg.png');
要点总结
- 一次性转换,浏览器工具最快。
- 命令行使用时,Inkscape 对复杂 SVG 的渲染最准确。
- Node.js 批量处理,
sharp速度快且能正确处理大多数 SVG。 - Python 批量处理,
cairosvg和 Inkscape 使用同一个渲染器。 - 导出为 CSS 显示尺寸的 2×,用于视网膜/高 DPI 屏幕。
- PNG 保留透明度——除非需要,不必加白色背景。