Basj
Basj

Reputation: 46353

Convert SVG to PNG with Python on Windows

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:

So a solution - specific for Windows - would be helpful.

Upvotes: 11

Views: 6959

Answers (3)

Cees Timmerman
Cees Timmerman

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

coproc
coproc

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:

  1. Install CairoSVG, i.e. pip install CairoSVG
  2. If libcairo-2.dll is not on the Windows path of your computer (i.e. 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

Luke Woodward
Luke Woodward

Reputation: 65054

From the comments, the solution was to install svglib version 1.0.1 and reportlab 3.5.59.

Upvotes: 10

Related Questions