2010-05-28 1 views
11

В настоящее время я использую rsvg для загрузки svg (из строки, а не из файла) и рисования в cairo. Кто-нибудь знает лучший способ? Я использую PIL в другом месте в своем приложении, но я не знаю, как это сделать с PIL.Server-side SVG to PNG (или какой-либо другой формат изображения) в python

+0

PIL не поддерживает SVG; быстрый поиск показывает, что у вас, вероятно, есть правильная инструментальная цепочка. – msw

+0

Я только что опубликовал более свежий комментарий об этом здесь - http://stackoverflow.com/a/19718153/542550 - нижеприведенный комментарий гласит, что «поддержка ImageMagick кажется ужасной», но этот комментатор не создавал ее/Попробуй это. Сейчас 10/2013, и я только что проверил с помощью ImageMagick (через Wand-py), чтобы импортировать большое количество SVG, и это сработало отлично! У меня все еще есть больше тестов, и я обязательно проиграю этот комментарий, если я ужасно ошибаюсь, но на данный момент он безупречно работал над несколькими SVG, которые, как известно, были ошибочными, используя другие методы. – streetlogics

ответ

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! Общее правило заключается в том, что то, что вы публикуете, является способом решения проблемы, тогда это может быть ответ; если это контекст или попытки решить проблему, которая не работает, или почувствовать, что ее взломали, чтобы быть хорошим ответом, тогда она должна идти в вопросе как редактирование. Тот факт, что этот код, похоже, «то, что вы делаете», о котором вы хотели получить, («Кто-нибудь знает лучший способ»), а не решение проблемы, говорит о том, что это действительно должно быть в вашем вопросе. –

+0

Внутри есть некоторые ошибки. При создании ImageSurface вам понадобится Integer 'surface = cairo.ImageSurface (cairo.FORMAT_ARGB32, round (int (x)), round (int (y))' И вы должны убедиться, что maxwidth и maxheight всегда заданы большим числом который был бы лучше 0. У меня много SVG с высотой 32000, что приведет к ошибке памяти. – therealmarv

2

Как насчет imagemagic? - http://www.imagemagick.org/script/magick-vector-graphics.php Он может читать/писать с/на stdin/stdout, поэтому вы можете интегрировать его с вашим приложением, даже если вы не хотите использовать файлы.

+0

ImageMagick 'convert' версии старше мая 2010 года делают ужасную работу по интерпретации SVG. Учитывая, что в журнале изменений это не выглядит например, они еще не получили поддержку SVG (хотя я ее не собирал). – msw

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 [Access Denied] (или что-то подобное), пока я не перешел в каталог Inkscape

+1

Рассмотрим переход 'cwd = inkscape_dir' к' Popen', вместо того, чтобы изменять каталог для родительского процесса. –

2

Вы также можете нас е PhantomJS для этого (см http://phantomjs.org/screen-capture.html)

Из оболочки:

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

Или из питона с помощью селена:

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') 
Смежные вопросы