在Python中将SVG转换为PNG

如何在Python中将svg转换为png ? 我将svg存储在一个StringIO的实例中。 我应该使用pyCairo库吗? 我如何编写代码?

答案是“ pyrsvg ” – 一个librsvg的Python绑定。

有一个提供它的Ubuntu python-rsvg软件包 。 search谷歌的名字很差,因为它的源代码似乎被包含在“gnome-python-desktop”Gnome项目的GIT仓库中。

我做了一个极简主义的“hello world”,将SVG渲染到一个cairo表面并写入磁盘:

 import cairo import rsvg img = cairo.ImageSurface(cairo.FORMAT_ARGB32, 640,480) ctx = cairo.Context(img) ## handle = rsvg.Handle(<svg filename>) # or, for in memory SVG data: handle= rsvg.Handle(None, str(<svg data>)) handle.render_cairo(ctx) img.write_to_png("svg.png") 

更新 :截至2014年,Fedora Linux发行版所需的软件包是: gnome-python2-rsvg 。 上面的代码片段仍然按原样运行。

这是我使用cairosvg所做的 :

 from cairosvg import svg2png svg_code = """ <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#000" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <circle cx="12" cy="12" r="10"/> <line x1="12" y1="8" x2="12" y2="12"/> <line x1="12" y1="16" x2="12" y2="16"/> </svg> """ svg2png(bytestring=svg_code,write_to='output.png') 

它就像一个魅力!

查看更多: cairosvg文件

安装Inkscape并将其命名为命令行:

 ${INKSCAPE_PATH} -z -f ${source_svg} -w ${width} -j -e ${dest_png} 

您也可以使用参数-j捕捉特定的矩形区域,例如坐标“0:125:451:217”

 ${INKSCAPE_PATH} -z -f ${source_svg} -w ${width} -j -a ${coordinates} -e ${dest_png} 

如果要在SVG文件中仅显示一个对象,则可以使用在SVG中设置的对象ID指定参数-i 。 它隐藏了一切。

 ${INKSCAPE_PATH} -z -f ${source_svg} -w ${width} -i ${object} -j -a ${coordinates} -e ${dest_png} 

我正在使用Wand-py (ImageMagick周围的Wand wrapper的实现)来导入一些非常先进的SVG,到目前为止已经看到了很好的结果! 这是所有的代码:

  with wand.image.Image( blob=svg_file.read(), format="svg" ) as image: png_image = image.make_blob("png") 

我今天刚刚发现了这个问题,觉得值得与其他人分享这个问题,因为这些问题大部分已经回答了,因为这已经有一段时间了。

注:技术上在testing中,我发现你甚至不必传递ImageMagick的格式参数,所以with wand.image.Image( blob=svg_file.read() ) as image:是真正需要的。

编辑:从试图编辑由克里斯,这里有一些有用的代码,可以让你使用ImageMagick具有透明背景的SVG:

 from wand.api import library import wand.color import wand.image with wand.image.Image() as image: with wand.color.Color('transparent') as background_color: library.MagickSetBackgroundColor(image.wand, background_color.resource) image.read(blob=svg_file.read(), format="svg") png_image = image.make_blob("png32") with open(output_filename, "wb") as out: out.write(png_image) 

试试这个: http : //cairosvg.org/

该网站说:

CairoSVG是用纯python编写的,只取决于Pycairo。 已知在Python 2.6和2.7上工作。

2016年11月25日 更新

2.0.0是一个新的主要版本,其更新日志包括:

  • 删除Python 2的支持

我刚刚在这里find的另一个解决scheme如何呈现一个缩放的SVG到QImage?

 from PySide.QtSvg import * from PySide.QtGui import * def convertSvgToPng(svgFilepath,pngFilepath,width): r=QSvgRenderer(svgFilepath) height=r.defaultSize().height()*width/r.defaultSize().width() i=QImage(width,height,QImage.Format_ARGB32) p=QPainter(i) r.render(p) i.save(pngFilepath) p.end() 

PySide很容易从Windows中的二进制包安装(我用它来做其他事情,所以对我来说很简单)。

但是,我注意到从Wikimedia转换国家标志的一些问题,所以也许不是最健壮的SVGparsing器/渲染器。

jsbueno的答案有点延伸:

 #!/usr/bin/env python import cairo import rsvg from xml.dom import minidom def convert_svg_to_png(svg_file, output_file): # Get the svg files content with open(svg_file) as f: svg_data = f.read() # Get the width / height inside of the SVG doc = minidom.parse(svg_file) width = int([path.getAttribute('width') for path in doc.getElementsByTagName('svg')][0]) height = int([path.getAttribute('height') for path in doc.getElementsByTagName('svg')][0]) doc.unlink() # create the png img = cairo.ImageSurface(cairo.FORMAT_ARGB32, width, height) ctx = cairo.Context(img) handler = rsvg.Handle(None, str(svg_data)) handler.render_cairo(ctx) img.write_to_png(output_file) if __name__ == '__main__': from argparse import ArgumentParser parser = ArgumentParser() parser.add_argument("-f", "--file", dest="svg_file", help="SVG input file", metavar="FILE") parser.add_argument("-o", "--output", dest="output", default="svg.png", help="PNG output file", metavar="FILE") args = parser.parse_args() convert_svg_to_png(args.svg_file, args.output) 

这是一个端到端的Python示例。

请注意,它禁止在正常无错操作期间Inkscape写入控制台(特别是stderr和stdout)的特定输出。 输出被捕获到两个stringvariablesouterr

 import subprocess # May want to use subprocess32 instead cmd_list = [ '/full/path/to/inkscape', '-z', '--export-png', '/path/to/output.png', '--export-width', 100, '--export-height', 100, '/path/to/input.svg' ] # Invoke the command. Divert output that normally goes to stdout or stderr. p = subprocess.Popen( cmd_list, stdout=subprocess.PIPE, stderr=subprocess.PIPE ) # Below, < out > and < err > are strings or < None >, derived from stdout and stderr. out, err = p.communicate() # Waits for process to terminate # Maybe do something with stdout output that is in < out > # Maybe do something with stderr output that is in < err > if p.returncode: raise Exception( 'Inkscape error: ' + (err or '?') ) 

例如,当在我的Mac OS系统上运行一个特定的工作时,结果是:

 Background RRGGBBAA: ffffff00 Area 0:0:339:339 exported to 100 x 100 pixels (72.4584 dpi) Bitmap saved as: /path/to/output.png 

(input的svg文件的大小为339×339像素。)