SVG representación en un PyGame aplicación

En un pyGame aplicación, me gustaría resolución de render libre GUI widgets se describe en SVG.

Lo de la herramienta y/o de la biblioteca se puede utilizar para alcanzar este objetivo ?

(Me gusta la OCEMP GUI toolkit pero parece ser de mapa de bits dependen para su representación)

  • Hay una respuesta diferente / la biblioteca que se aplica a 2011? (porque ha sido 3 años). He visto squirtle se utiliza para cargar los mapas creados en inkscape.
  • Squirtle es que todavía no apoyar mucho de SVG afaik y conseguir que se ejecute con PyGame, probablemente, también requiere un poco de trabajo. Estoy buscando por un largo tiempo para soporte de SVG dibujo en Windows y 64 Bits de Python y creo que tengo que dejar.
  • El tiempo pasa, las nuevas posibilidades que surgen. Ver mi respuesta, pero espere, aún hay más! pynanosvg tiene paquete binario para Windows!

8 Kommentare

  1. 16

    Este es un ejemplo completo que combina sugerencias de otras personas que están aquí.
    Debería hacer un archivo llamado prueba.svg desde el directorio actual. Fue probado en Ubuntu 10.10, python-el cairo 1.8.8, python-pygame 1.9.1, python-rsvg 2.30.0.

    #!/usr/bin/python
    
    import array
    import math
    
    import cairo
    import pygame
    import rsvg
    
    WIDTH = 512
    HEIGHT = 512
    
    data = array.array('c', chr(0) * WIDTH * HEIGHT * 4)
    surface = cairo.ImageSurface.create_for_data(
        data, cairo.FORMAT_ARGB32, WIDTH, HEIGHT, WIDTH * 4)
    
    pygame.init()
    window = pygame.display.set_mode((WIDTH, HEIGHT))
    svg = rsvg.Handle(file="test.svg")
    ctx = cairo.Context(surface)
    svg.render_cairo(ctx)
    
    screen = pygame.display.get_surface()
    image = pygame.image.frombuffer(data.tostring(), (WIDTH, HEIGHT),"ARGB")
    screen.blit(image, (0, 0)) 
    pygame.display.flip() 
    
    clock = pygame.time.Clock()
    while True:
        clock.tick(15)
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                raise SystemExit
    • la razón de no utilizar screen = pygame.display.set_mode((WIDTH, HEIGHT)) directamente en lugar de la creación de este window objeto que nunca se utiliza?
  2. 6

    La pregunta es bastante antiguo, pero 10 años pasaron y hay una nueva posibilidad de que funciona y no requiere librsvg más. Hay Cython contenedor a través de nanosvg biblioteca y funciona:

    from svg import Parser, Rasterizer
    
    
    def load_svg(filename, surface, position, size=None):
        if size is None:
            w = surface.get_width()
            h = surface.get_height()
        else:
            w, h = size
        svg = Parser.parse_file(filename)
        rast = Rasterizer()
        buff = rast.rasterize(svg, w, h)
        image = pygame.image.frombuffer(buff, (w, h), 'ARGB')
        surface.blit(image, position)

    He encontrado el Cairo/rsvg solución demasiado complicado para llegar a su trabajo debido a las dependencias son bastante oscuro para instalar.

  3. 5

    Puede utilizar El Cairo (con PyCairo), que tiene soporte para el renderizado de SVGs. La PyGame página web tiene un HOWTO para la representación en un búfer con una de el Cairo, y el uso que el buffer directamente con PyGame.

  4. 4

    Me doy cuenta de que esto no es exactamente la respuesta a su pregunta, pero hay una librería llamada Squirtle que preste los archivos SVG utilizando Pyglet o PyOpenGL.

  5. 3

    pygamesvg parece hacer lo que quiera (aunque yo no lo he probado).

    • Dicho módulo ha sido retirado. El cairo+rsvg enfoques que figuran a continuación son mucho mejores soluciones. [descargo de responsabilidad: yo rápidamente escribió pygamesvg hace 3 años]
  6. 2

    El Cairo no se puede representar SVG fuera de la caja.
    Parece que tenemos que usar librsvg.

    Acabo de encontrar estas dos páginas:

    Algo como esto probablemente debería trabajo (render de la prueba.svg a de la prueba.png):

    import cairo
    import rsvg
    
    WIDTH, HEIGHT  = 256, 256
    surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, WIDTH, HEIGHT)
    
    ctx = cairo.Context (surface)
    
    svg = rsvg.Handle(file="test.svg")
    svg.render_cairo(ctx)
    
    surface.write_to_png("test.png")
  7. 1

    El último comentario se estrelló cuando lo corrió porque svg.render_cairo() está a la espera de el cairo contexto y no de el cairo de la superficie. He creado y probado de la siguiente función y parece correr bien en mi sistema.

    import array,cairo, pygame,rsvg
    
    def loadsvg(filename,surface,position):
        WIDTH = surface.get_width()
        HEIGHT = surface.get_height()
        data = array.array('c', chr(0) * WIDTH * HEIGHT * 4)
        cairosurface = cairo.ImageSurface.create_for_data(data, cairo.FORMAT_ARGB32, WIDTH, HEIGHT, WIDTH * 4)
        svg = rsvg.Handle(filename)
        svg.render_cairo(cairo.Context(cairosurface))
        image = pygame.image.frombuffer(data.tostring(), (WIDTH, HEIGHT),"ARGB")
        surface.blit(image, position) 
    
    WIDTH = 800
    HEIGHT = 600
    pygame.init()
    window = pygame.display.set_mode((WIDTH, HEIGHT))
    screen = pygame.display.get_surface()
    
    loadsvg("test.svg",screen,(0,0))
    
    pygame.display.flip() 
    
    clock = pygame.time.Clock()
    while True:
        clock.tick(15)
        event = pygame.event.get()
        for e in event:
            if e.type == 12:
                raise SystemExit
  8. 0

    Basado en otras respuestas, he aquí una función para leer un archivo SVG en un pygame imagen – incluyendo la corrección de color de la canal de la orden y la escala:

    def pygame_svg( svg_file, scale=1 ):
        svg = rsvg.Handle(file=svg_file)
        width, height= map(svg.get_property, ("width", "height"))
        width*=scale; height*=scale
        data = array.array('c', chr(0) * width * height * 4)
        surface = cairo.ImageSurface.create_for_data( data, cairo.FORMAT_ARGB32, width, height, width*4)
        ctx = cairo.Context(surface)
        ctx.scale(scale, scale)
        svg.render_cairo(ctx)
    
        #seemingly, cairo and pygame expect channels in a different order...
        #if colors/alpha are funny, mess with the next lines
        import numpy
        data= numpy.fromstring(data, dtype='uint8')
        data.shape= (height, width, 4)
        c= data.copy()
        data[::,::,0]=c[::,::,1]
        data[::,::,1]=c[::,::,0]
        data[::,::,2]=c[::,::,3]
        data[::,::,3]=c[::,::,2]
    
        image = pygame.image.frombuffer(data.tostring(), (width, height),"ARGB")
        return image

Kommentieren Sie den Artikel

Bitte geben Sie Ihren Kommentar ein!
Bitte geben Sie hier Ihren Namen ein

Pruebas en línea