如何在 Python 中将 SVG 图像渲染为 PNG 文件?
How to render SVG image to PNG file in Python?
所以我想从具有目标分辨率 WxH 的 python 代码渲染 SVG(将 SVG 文本作为 str,我动态生成的 like this):
<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>
转换为 png 图像。在Python中如何做这样的事情?
你可以使用CairoSVG
CairoSVG 在 PyPI 上可用,您可以使用 pip 安装它:
pip3 install cairosvg
在您的代码中:
import cairosvg
width = 640
height = 480
cairosvg.svg2png(url='logo.svg', write_to='image.png', output_width=width, output_height=height)
python 中有多种解决方案可用于将 svg 转换为 png,但并非所有解决方案都适用于您的特定用例,因为您正在使用 svg 过滤器。
solution
filter works?
alpha channel?
call directly from python?
cairosvg
some*
yes
yes
svglib
no
no
yes
inkscape
yes
yes
via subprocess
wand
yes
yes
yes
* 来自 cairosvg documentation:
Only feOffset
, feBlend
and feFlood
filters are supported.
注意:我为所有样本图像添加了纯白色背景,以便在深色背景下更容易看到它们,除非在上面 table 中说明,否则原件确实具有透明背景
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')
要读取文件作为输入,请将文件路径作为最后一个参数。
要使用字符串作为输入,请添加 --pipe
参数并将字符串传递给标准输入。
要写入文件作为输出,请添加参数 --export-filename=
+输出文件的路径。
要直接获取输出内容而不写入文件,请使用 --export-filename=-
并将其发送到标准输出。
CLI 选项的完整文档here
import subprocess
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)
from wand.image import Image
from wand.Color import Color
with Color('#00000000') as bgcolor,\
# to read input from a file:
Image(filename=input_svg_path, width=width, height=height, background=bgcolor) as img:
# or, to use input from a string:
Image(blob=svg_str.encode(), format='svg', width=width, height=height, background=bgcolor) as img:
# to save output to a file:
with img.convert('png') as output_img:
output_img.save(filename=output_png_path)
# or, to get the output data in a variable:
png_data = img.make_blob(format='png')
所以我想从具有目标分辨率 WxH 的 python 代码渲染 SVG(将 SVG 文本作为 str,我动态生成的 like this):
<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>
转换为 png 图像。在Python中如何做这样的事情?
你可以使用CairoSVG
CairoSVG 在 PyPI 上可用,您可以使用 pip 安装它:
pip3 install cairosvg
在您的代码中:
import cairosvg
width = 640
height = 480
cairosvg.svg2png(url='logo.svg', write_to='image.png', output_width=width, output_height=height)
python 中有多种解决方案可用于将 svg 转换为 png,但并非所有解决方案都适用于您的特定用例,因为您正在使用 svg 过滤器。
solution | filter works? | alpha channel? | call directly from python? |
---|---|---|---|
cairosvg | some* | yes | yes |
svglib | no | no | yes |
inkscape | yes | yes | via subprocess |
wand | yes | yes | yes |
* 来自 cairosvg documentation:
Only
feOffset
,feBlend
andfeFlood
filters are supported.
注意:我为所有样本图像添加了纯白色背景,以便在深色背景下更容易看到它们,除非在上面 table 中说明,否则原件确实具有透明背景
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')
要读取文件作为输入,请将文件路径作为最后一个参数。
要使用字符串作为输入,请添加 --pipe
参数并将字符串传递给标准输入。
要写入文件作为输出,请添加参数 --export-filename=
+输出文件的路径。
要直接获取输出内容而不写入文件,请使用 --export-filename=-
并将其发送到标准输出。
CLI 选项的完整文档here
import subprocess
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)
from wand.image import Image
from wand.Color import Color
with Color('#00000000') as bgcolor,\
# to read input from a file:
Image(filename=input_svg_path, width=width, height=height, background=bgcolor) as img:
# or, to use input from a string:
Image(blob=svg_str.encode(), format='svg', width=width, height=height, background=bgcolor) as img:
# to save output to a file:
with img.convert('png') as output_img:
output_img.save(filename=output_png_path)
# or, to get the output data in a variable:
png_data = img.make_blob(format='png')