2010-05-28 78 views
11

目前,我正在使用rsvg加载svg(从字符串,而不是从文件)并绘制到cairo。任何人都知道更好的方法?我在我的应用程序的其他地方使用PIL,但我不知道用PIL做这件事的方法。蟒蛇服务器端SVG到PNG(或其他一些图像格式)

+0

PIL不支持SVG;一个快速的冲浪表明你可能有正确的工具链。 – msw 2010-05-28 22:30:24

+0

我刚刚在这里发布了关于此的更新评论 - http://stackoverflow.com/a/19718153/542550 - 下面的评论指出“ImageMagick支持似乎很糟糕”,但该评论者没有构建它/测试它。现在是2013年10月,我刚刚使用ImageMagick进行了测试(通过Wand-py)导入了各种各样的SVG,并且效果很好!我仍然有更多的测试要做,如果我真的犯了错误,我肯定会把这个评论拉下来,但是现在它已经在一些SVG上完美地工作了,这些SVG被称为使用其他方法的越野车。 – streetlogics 2013-10-31 23:12:51

回答

12

这是我目前有:

import cairo 
import rsvg 

def convert(data, ofile, maxwidth=0, maxheight=0): 

    svg = rsvg.Handle(data=data) 

    x = width = svg.props.width 
    y = height = svg.props.height 
    print "actual dims are " + str((width, height)) 
    print "converting to " + str((maxwidth, maxheight)) 

    yscale = xscale = 1 

    if (maxheight != 0 and width > maxwidth) or (maxheight != 0 and height > maxheight): 
     x = maxwidth 
     y = float(maxwidth)/float(width) * height 
     print "first resize: " + str((x, y)) 
     if y > maxheight: 
      y = maxheight 
      x = float(maxheight)/float(height) * width 
      print "second resize: " + str((x, y)) 
     xscale = float(x)/svg.props.width 
     yscale = float(y)/svg.props.height 

    surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, x, y) 
    context = cairo.Context(surface) 
    context.scale(xscale, yscale) 
    svg.render_cairo(context) 
    surface.write_to_png(ofile) 
+3

欢迎来到Stackoverflow!一般的经验法则是,如果你发布的是解决问题的方法,那么它可能是一个答案;如果是上下文或试图解决不起作用的问题,或者认为被黑客入侵是一个很好的答案,那么它应该作为编辑来解决问题。事实上,这段代码似乎是你想要获得评论的'你正在做的'(“任何人都知道更好的方法”),而不是解决问题的方法,这表明这应该是你的问题。 – 2010-05-28 22:02:26

+0

里面有一些错误。当你创建一个ImageSurface时,你需要Integer'表面= cairo.ImageSurface(cairo.FORMAT_ARGB32,round(int(x)),round(int(y))'你应该确保maxwidth和maxheight总是被设置为一个高数字这会比0更好我有很多SVG的高度是32000,这会导致内存错误 – therealmarv 2011-12-09 04:49:51

2

如何imagemagic? - http://www.imagemagick.org/script/magick-vector-graphics.php它可以读/写标准输入/标准输出,所以你可以将它与你的应用程序集成,即使你不想使用文件

+0

2010年5月以前的ImageMagick'convert'版本在解释SVG方面做了很糟糕的工作,就像他们还没有得到SVG支持一样正常工作(虽然我没有建立它看) – msw 2010-05-28 22:29:01

1

我已经安装了inkscape,所以我只是将这个过程用于inkscape与inkscape -f file.svg -e file.png

使用此代码的命令:

import subprocess 
inkscape_dir=r"C:\Program Files (x86)\Inkscape" 
assert os.path.isdir(inkscape_dir) 
os.chdir(inkscape_dir) 
subprocess.Popen(['inkscape.exe',"-f",fname,"-e",fname_png]) 

我在Windows 7中,并得到了Windows的5错误[拒绝访问(或类似的东西),直到我切换到Inkscape的目录

+1

考虑将'cwd = inkscape_dir'传递给'Popen',而不是改变父进程的目录。 – 2011-10-01 20:06:06

2

你也可以

phantomjs rasterize.js http://ariya.github.com/svg/tiger.svg tiger.png 

或者从使用Python中的硒:对于这个电子PhantomJS(见http://phantomjs.org/screen-capture.html

从外壳

from selenium import webdriver 
driver = webdriver.PhantomJS() 
driver.set_window_size(1024, 768) 
driver.get('http://ariya.github.com/svg/tiger.svg') 
driver.save_screenshot('tiger.png')