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?
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)
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
andfeFlood
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
import cairosvg
# read svg file -> write png file
cairosvg.svg2png(url=input_svg_path, write_to=output_png_path, output_width=width, output_height=height)
# read svg file -> png data
png_data = cairosvg.svg2png(url=input_svg_path, output_width=width, output_height=height)
# svg string -> write png file
cairosvg.svg2png(bytestring=svg_str.encode(), write_to=output_png_path, output_width=width, output_height=height)
# svg string -> png data
png_data = cairosvg.svg2png(bytestring=svg_str.encode(), output_width=width, output_height=height)
from svglib.svglib import svg2rlg
from reportlab.graphics import renderPM
# read svg -> write png
renderPM.drawToFile(svg2rlg(input_svg_path), output_png_path, fmt='PNG')
full documentation for CLI options here
import os
inkscape = ... # path to inkscape executable
# read svg file -> write png file
subprocess.run([inkscape, '--export-type=png', f'--export-filename={output_png_path}', f'--export-width={width}', f'--export-height={height}', input_svg_path])
# read svg file -> png data
result = subprocess.run([inkscape, '--export-type=png', '--export-filename=-', f'--export-width={width}', f'--export-height={height}', input_svg_path], capture_output=True)
# (result.stdout will have the png data)
# svg string -> write png file
subprocess.run([inkscape, '--export-type=png', f'--export-filename={output_png_path}', f'--export-width={width}', f'--export-height={height}', '--pipe'], input=svg_str.encode())
# svg string -> png data
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)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.