2010-05-28 14 views
11

Actualmente estoy usando rsvg para cargar svg (desde una cadena, no desde un archivo) y dibujar en cairo. Alguien sabe una mejor manera? Uso PIL en otra parte de mi aplicación, pero no sé cómo hacerlo con PIL.SVG del lado del servidor a PNG (o algún otro formato de imagen) en python

+0

PIL no soporta SVG; una navegación rápida indica que probablemente tenga la cadena de herramientas correcta. – msw

+0

Acabo de publicar un comentario más reciente sobre esto aquí - http://stackoverflow.com/a/19718153/542550 - un comentario a continuación indica que "el soporte de ImageMagick parece ser terrible", pero ese comentarista no lo compiló/Pruébalo. Ahora es 10/2013, y acabo de probar usando ImageMagick (a través de Wand-py) para importar una gran variedad de SVG y ¡funcionó de maravilla! Todavía tengo más pruebas que hacer y definitivamente reduciré este comentario si estoy terriblemente equivocado, pero en este punto ha funcionado perfectamente en algunos SVG conocidos por tener otros métodos. – streetlogics

Respuesta

12

Esto es lo que tengo actualmente:

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

¡Bienvenido a Stackoverflow! La regla general es si lo que está publicando es una forma de resolver el problema, entonces puede ser una respuesta; si es contexto o intentos de resolver el problema que no funcionan, o se sienten pirateados para ser una buena respuesta, entonces debería incluirse en la pregunta como una edición. El hecho de que este código parece ser el 'qué estabas haciendo' que buscabas para comentar, ("Cualquiera conoce una mejor manera") en lugar de una solución a un problema sugiere que esto realmente debería estar en tu pregunta. –

+0

Hay algunos errores dentro. Cuando creas una superficie de imagen, necesitas un entero 'surface = cairo.ImageSurface (cairo.FORMAT_ARGB32, round (int (x)), round (int (y))' Y debes asegurarte de que maxwidth y maxheight estén siempre configurados en un número alto que sería mejor que 0. Tengo muchos SVG con alturas de 32000 que darán como resultado un error de memoria. – therealmarv

2

¿Qué tal ImageMagic? - http://www.imagemagick.org/script/magick-vector-graphics.php Puede leer/escribir desde/a stdin/stdout para que pueda integrarlo con su aplicación incluso si no desea usar los archivos

+0

Las versiones de ImageMagick 'convert' anteriores a mayo de 2010 hacen un trabajo horrible al interpretar SVG. Dado el registro de cambios, no parece como si todavía tuvieran compatibilidad SVG funcionando bien (aunque no lo construí para ver). – msw

1

Tengo instalado Inkscape, así que solo estoy trabajando en el proceso de inkscape comando con inkscape -f file.svg -e file.png

Utilizando este código:

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]) 

estoy en windows 7, y obtuvo el de windows 5 Error [Acceso denegado] (o algo así) hasta que me cambié al directorio inkscape

+1

Considere pasar 'cwd = inkscape_dir' a' Popen', en lugar de cambiar el directorio para el proceso principal. –

2

También nos puedes e PhantomJS para ello (ver http://phantomjs.org/screen-capture.html)

Desde un shell:

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

O de Python usando el selenio:

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') 
Cuestiones relacionadas