问题:哪个可重现的过程可以使 Windows Python 用户将 SVG 图像渲染为 PNG?
许多问题/答案(例如 Convert SVG to PNG in Python 和 Server-side SVG to PNG (or some other image format) in python,由于下面解释的原因,这些问题/答案不重复)解释了如何将使用 Python 将 SVG 转为 PNG。
不幸的是,它们都不适用于 Python + Windows。经过20多分钟的尝试,我仍然无法做到。 有关失败尝试的更多详细信息:
在 Windows 上安装
cairo
并不简单,我们必须使用 Gohlke 的二进制文件 在 Windows 上使用 Python 3.7 安装 pycairo :
pip install pycairo-1.20.0-cp37-cp37m-win_amd64.whl
即使安装了
cairo
,rsvg
(来自Server-side SVG to PNG (or some other image format) in python,Convert SVG to PNG in Python的主要答案)不适用于Windows :
pip install rsvg # or pyrsvg
> ERROR: No matching distribution found for pyrsvg
带有
svglib
或 reportlab
的解决方案不能在 Python3 + Windows 上开箱即用:
from svglib.svglib import svg2rlg
from reportlab.graphics import renderPDF, renderPM
drawing = svg2rlg("a.svg")
renderPM.drawToFile(drawing, "file.png", fmt="PNG")
确实:
AttributeError: 'Image' object has no attribute 'fromstring'
因此,专门针对 Windows 的解决方案会有所帮助。
从评论来看,解决方案是安装
svglib
版本1.0.1和reportlab
3.5.59。
在比较了几种解决方案并找出如何让 libcairo 在 Windows 计算机上工作(这可能有点棘手)之后,我推荐以下相当简单的解决方案:
pip install CairoSVG
where libcairo-2.dll
失败)并且您不知道在哪里找到它,请安装 GTK+ Runtime(<8 MB download, 14 MB when installed) with checkbox 设置 PATH 环境变量以包含 GTK+ 检查) (或者自己提供下面的DLL文件夹路径)然后使用这个Python脚本进行转换:
import os
import subprocess
import sys
# locate cairo dll
def _findLibCairoInstallFolder():
CAIRO_DLL = 'libcairo-2.dll'
consoleOutput = subprocess.check_output('where ' + CAIRO_DLL)
assert CAIRO_DLL.encode() in consoleOutput,\
f"{CAIRO_DLL} not on Windows path. Do you know its install folder? Have you the GTK+ Runtime for Windows installed?"
cairoDllFirstLocation = consoleOutput.split(b'\r\n')[0].decode()
cairoDllInstallPath = cairoDllFirstLocation.split(CAIRO_DLL)[0]
return cairoDllInstallPath
# find or provide path to installation folder of cairo dll
g_cairoDllInstallPath = _findLibCairoInstallFolder()
#g_cairoDllInstallPath = r"C:\Program Files (x86)\GTK2-Runtime\bin"
# locally fix windows environment variable PATH so that libcairo-2.dll can be loaded
def _fixWindowsPathForLibCairo(cairoDllInstallPath):
# make sure dependencies like zlib1.dll are loaded from the same folder
os.environ['PATH'] = os.pathsep.join((cairoDllInstallPath, os.environ['PATH']))
_fixWindowsPathForLibCairo(g_cairoDllInstallPath)
import cairosvg
PATH_TO_SVG = 'example.svg'
def svg2png(inputPath, outputPath):
with open(inputPath) as fileIn:
svgCode = fileIn.read()
cairosvg.svg2png(bytestring=svgCode, write_to=outputPath)
if __name__ == '__main__':
if len(sys.argv) > 1:
g_inputPath = sys.argv[1]
else:
g_inputPath = PATH_TO_SVG
if len(sys.argv) > 2:
g_outputPath = sys.argv[2]
else:
g_outputPath = g_inputPath + '.png'
svg2png(g_inputPath, g_outputPath)