2008-09-23 13 views
19

En una aplicación pyGame, me gustaría mostrar los widgets GUI sin resolución descritos en SVG.Representación SVG en una aplicación PyGame

¿Qué herramienta y/o biblioteca puedo usar para alcanzar este objetivo?

(me gusta el juego de herramientas OCEMP GUI pero parece ser dependiente de mapa de bits por su prestación)

+2

¿Hay una respuesta/biblioteca diferente que se aplica a 2011 ? (porque ha sido hace 3 años). He visto squirtle usado para cargar mapas creados en ** inkscape **. – ninMonkey

+0

Squirtle aún no admite gran parte de SVG afaik y hacer que funcione con PyGame probablemente también requiera algo de trabajo. Estoy buscando mucho tiempo para el soporte de dibujo SVG en Windows y 64 Bit Python y creo que tengo que darme por vencido. – Trilarion

Respuesta

15

Este es un ejemplo completo que combina consejos de otras personas aquí. Debería representar un archivo llamado test.svg desde el directorio actual. Fue probado en Ubuntu 10.10, python-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 
+1

¿Alguna razón en particular para no usar 'screen = pygame.display.set_mode ((ANCHO, ALTURA))' directamente en lugar de crear este objeto 'window' que nunca se usa? – MestreLion

4

Usted puede utilizar Cairo (con PyCairo), que cuenta con el apoyo para la prestación de IVS. La página web de PyGame tiene un HOWTO para representar en un búfer con un Cairo, y usar ese búfer directamente con PyGame.

4

Me doy cuenta de que esto no responde exactamente a su pregunta, pero hay una biblioteca llamada Squirtle que procesará archivos SVG usando Pyglet o PyOpenGL.

2

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

acaba de encontrar esos dos páginas:

Algo como esto se debe probablemente el trabajo (render test.svg a 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") 
3

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

+5

Ese módulo ha sido eliminado. Los enfoques de cairo + rsvg detallados a continuación son soluciones mucho mejores. [descargo de responsabilidad: escribí pygamesvg rápidamente hace 3 años] – PAG

1

El último comentario se estrelló cuando me encontré con él porque svg.render_cairo() está esperando un contexto Cairo y no una superficie Cairo. Creé y probé la siguiente función y parece funcionar 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 
0

Basándonos en las otras respuestas, he aquí una función para leer un archivo SVG una imagen de pygame en - incluyendo la corrección de orden de los canales de color y escalado:

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