Reputation: 46353
Question: Which reproducible process can enable Windows Python users to render a SVG image into PNG?
Many questions/answers (such as Convert SVG to PNG in Python and Server-side SVG to PNG (or some other image format) in python, which are not duplicates for the reasons explained below) explain how to convert a SVG to PNG with Python.
Unfortunately, none of them are ready-to-use for Python + Windows. After more than 20 minutes, and many different attempts, I'm still unable to do it. More details about failing attempts:
Installing cairo
on Windows is not straightforward, we have to use Gohlke's binaries Intalling pycairo with Python 3.7 on Windows :
pip install pycairo-1.20.0-cp37-cp37m-win_amd64.whl
Even once cairo
is installed, rsvg
(from main answers of Server-side SVG to PNG (or some other image format) in python, Convert SVG to PNG in Python) is not available for Windows:
pip install rsvg # or pyrsvg
> ERROR: No matching distribution found for pyrsvg
Solutions with svglib
or reportlab
don't work out-of-the-box on Python3 + Windows:
from svglib.svglib import svg2rlg
from reportlab.graphics import renderPDF, renderPM
drawing = svg2rlg("a.svg")
renderPM.drawToFile(drawing, "file.png", fmt="PNG")
Indeed:
AttributeError: 'Image' object has no attribute 'fromstring'
So a solution - specific for Windows - would be helpful.
Upvotes: 11
Views: 6959
Reputation: 19684
I couldn't get cairosvg
to work in Windows, but found pygame
mostly works without the hassle of gathering libraries.
import pygame
surface = pygame.image.load("shrubbery.svg")
pygame.image.save(surface, "shrubbery.png")
WebP, AVIF, and JPEG XL are replacing PNG.
Upvotes: 1
Reputation: 6257
After comparing several solutions and finding out how to get libcairo working on a Windows computer (which can be a bit tricky) I recommend the following rather simple solution:
pip install CairoSVG
where libcairo-2.dll
fails) and you do not know where to find it, install the GTK+ Runtime (<8 MB download, 14 MB when installed) with checkbox Set up PATH environment variable to include GTK+ checked (or provide the DLL folder path below yourself)Now it can still happen that import cairosvg
fails because there might be incompatible dependencies like zlib1.dll
on your Windows path.
To avoid such complications use the following Python script for conversion, which makes sure that libcairo-2.dll
and its dependencies are loaded from the same folder. Provide the path to the SVG file as command line argument or in the global variable PATH_TO_SVG
:
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 _fixWindowsPathForLib(dllInstallPath):
# make sure dependencies are loaded from the same folder
os.environ['PATH'] = os.pathsep.join((dllInstallPath, os.environ['PATH']))
_fixWindowsPathForLib(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)
Upvotes: 0
Reputation: 65054
From the comments, the solution was to install svglib
version 1.0.1 and reportlab
3.5.59.
Upvotes: 10