Home > front end >  How to render SVG image to PNG file in Python?
How to render SVG image to PNG file in Python?

Time:11-01

So I want to render SVG from python code having target resolution WxH (having SVG text as str, like this that I generate dynamically):

<svg width="200" height="200" viewBox="0 0 220 220"
     xmlns="http://www.w3.org/2000/svg">
  <filter id="displacementFilter">
    <feTurbulence type="turbulence" baseFrequency="0.05"
        numOctaves="2" result="turbulence"/>
    <feDisplacementMap in2="turbulence" in="SourceGraphic"
        scale="50" xChannelSelector="R" yChannelSelector="G"/>
  </filter>

  <circle cx="100" cy="100" r="100"
      style="filter: url(#displacementFilter)"/>
</svg>

into a png image. How to do such a thing in Python?

CodePudding user response:

you can use CairoSVG

CairoSVG is available on PyPI, you can install it with pip:

pip3 install cairosvg

in your code:

import cairosvg

width = 640
height = 480
cairosvg.svg2png(url='logo.svg', write_to='image.png', output_width=width, output_height=height)

CodePudding user response:

solution filter works? alpha channel? call directly from python?
cairosvg no* yes yes
svglib no no yes
inkscape yes yes no**

* from cairosvg documentation:

Only feOffset, feBlend and feFlood filters are supported.

** calling external program via subprocess


note: i've added a solid white background to all the sample images to make them easier to see on a dark background, the originals did have transparent backgrounds unless stated in the table above


cairosvg

import cairosvg
cairosvg.svg2png(url='input.svg', write_to='output_cairosvg.png', output_width=200, output_height=200)

output from cairosvg


svglib

from svglib.svglib import svg2rlg
from reportlab.graphics import renderPM
renderPM.drawToFile(svg2rlg('input.svg'), 'output_svglib.png', fmt='PNG')

output from svglib


inkscape

output from inkscape

full documentation for CLI options here

import os
inkscape = ... # path to inkscape executable

# svg file -> png file
subprocess.run([inkscape, '--export-type=png', f'--export-filename={output_path}', f'--export-width={width}', f'--export-height={height}', input_path])

# svg string -> save png file
subprocess.run([inkscape, '--export-type=png', f'--export-filename={output_path}', f'--export-width={width}', f'--export-height={height}', '--pipe'], input=svg_str.encode())

# svg string -> png data in variable
result = subprocess.run([inkscape, '--export-type=png', '--export-filename=-', f'--export-width={width}', f'--export-height={height}', '--pipe'], input=svg_str.encode(), capture_output=True)
#   (result.stdout will have the png data as a bytes object)
  • Related