+
19
-

回答

在 Python 中将 SVG 图标转换为 PNG 图片,有多种方法,主要区别在于对系统依赖的要求和转换质量。下面按推荐程度介绍几种常用方案。

1. 使用 CairoSVG(推荐,纯 Python 调用 Cairo 库)

CairoSVG 是最常用的库,转换质量高,支持透明背景,可控制输出尺寸。

安装

pip install cairosvg

注意:CairoSVG 依赖系统的 Cairo 库。Windows 下通常需要额外安装 GTK 或下载 Cairo 的 DLL,最简单的方法是安装 pycairo 的预编译包,如 pip install pycairo‑‑only-binary=pycairo 或使用 conda:conda install -c conda-forge cairosvg。macOS 可用 brew install cairo,Linux 用 apt install libcairo2-dev。

示例代码

import cairosvg

# 从文件转换
cairosvg.svg2png(url="icon.svg", write_to="icon.png")

# 从字符串转换,控制输出尺寸(保持比例)
svg_str = '''<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
                <circle cx="50" cy="50" r="40" fill="blue"/>
             </svg>'''
cairosvg.svg2png(bytestring=svg_str.encode(), write_to="icon2.png",
                 output_width=512, output_height=512)

优点:抗锯齿好,支持大部分 SVG 特性。缺点:需要 Cairo 系统库;部分复杂 SVG 滤镜可能不支持。

2. 使用 svglib + reportlab(跨平台,纯 Python)

svglib 将 SVG 解析为 ReportLab 图形对象,再用 reportlab 渲染为位图。无需 C 扩展,部署更简单。

安装

pip install svglib reportlab

示例代码

from svglib.svglib import svg2rlg
from reportlab.graphics import renderPM

drawing = svg2rlg("icon.svg")
renderPM.drawToFile(drawing, "icon.png", fmt="PNG", dpi=300)

优点:纯 Python,无系统依赖,跨平台极佳。缺点:对复杂 SVG(如渐变、裁切路径)支持有限;输出可能需要手动设置尺寸。

3. 调用 Inkscape 命令行(保真度最高)

如果系统已安装 Inkscape,可直接通过命令行转换,几乎 100% 忠实还原 SVG。

示例代码

import subprocess

def svg_to_png_inkscape(svg_path, png_path, width=512):
    cmd = [
        "inkscape", svg_path,
        f"--export-width={width}",
        f"--export-filename={png_path}"
    ]
    # 老版本 Inkscape 参数不同,若失败可尝试:
    # cmd = ["inkscape", "-z", "-w", str(width), "-e", png_path, svg_path]
    subprocess.run(cmd, check=True)

svg_to_png_inkscape("icon.svg", "icon.png")

优点:完美支持 SVG 标准。缺点:必须安装 Inkscape;速度较慢;不适合无图形环境的服务器。

4. 其他可选方案

Wand + ImageMagick:需要 ImageMagick 和 MagickWand 库。

Pillow 间接转换:Pillow 本身不支持 SVG,但可通过 cairosvg 先转成 PNG 字节流再用 Pillow 处理,或借助 svglib 生成的位图。

resvg‑py / svg‑rendering 等绑定:调用 Rust 的 resvg 库,速度快、保真度高,但需要编译 Rust 扩展。

选择建议

一般开发、可接受系统依赖cairosvg(效果均衡)
纯 Python 环境、无 C 依赖svglib + reportlab
追求完美渲染Inkscape 命令行
高性能/批量转换resvg(需额外研究)

常见问题

Q:如何设置输出 PNG 的尺寸?使用 cairosvg 时指定 output_width / output_height,会保持 SVG 的宽高比自动缩放;svglib 可用 scale 因子或调整 dpi;Inkscape 用 --export-width。

Q:为什么转换后背景不透明?cairosvg 默认透明背景;svglib 默认白色背景,若需透明,需在绘图对象上设置背景为 None(较复杂,建议换用 cairosvg)。

Q:如何在内存中操作,不落盘?cairosvg.svg2png(bytestring=..., write_to=output_bytes_io),直接得到 PNG 字节数据。

根据你的开发环境和质量需求,选择最方便的一种即可。通常从 cairosvg 开始试,如果系统不便安装就回退到 svglib。

网友回复

我知道答案,我要回答