Pregunta

En un pyGame la 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 kit de herramientas, pero parece ser de mapa de bits dependen para su representación)

¿Fue útil?

Solución

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

Otros consejos

La pregunta es bastante antiguo, pero 10 años pasaron y hay una nueva posibilidad de que funciona y no requiere librsvg ya.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.

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.

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

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

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 prueba.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")

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

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
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top