Frage

In einer PyGame Anwendung würde Ich mag Auflösung freier GUI-Widgets beschrieben in SVG machen.

Welches Werkzeug und / oder Bibliothek kann ich dieses Ziel zu erreichen benutzen?

(Ich mag die OCEMP GUI Toolkit, aber es scheint Bitmap abhängig für seine Rendering zu sein)

War es hilfreich?

Lösung

Dies ist ein vollständiges Beispiel, das hier Hinweise von anderen Menschen verbindet. Es sollte eine Datei test.svg aus dem aktuellen Verzeichnis mit dem Namen machen. Es wurde auf Ubuntu getestet 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

Andere Tipps

Die Frage ist ziemlich alt, aber 10 Jahre vergangen und es gibt neue Möglichkeit, die funktioniert und erfordert keinen librsvg mehr. Es gibt Cython Wrapper über nanosvg Bibliothek und es funktioniert:

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)

Ich fand Kairo / RSVG Lösung zu kompliziert zu bekommen, da Abhängigkeiten zu arbeiten ganz dunkel ist zu installieren.

Sie können mit Kairo (mit PyCairo), die für das Rendern SVGs Unterstützung hat. Die PyGame Webseite hat eine HOWTO mit Kairo in einen Puffer zu machen, und die Verwendung dieser Puffer direkt mit PyGame.

Ich weiß, das beantwortet nicht genau Ihre Frage, aber es gibt eine Bibliothek mit dem Namen Squirtle dass SVG-Dateien entweder mit Pyglet oder PyOpenGL machen wird.

pygamesvg scheint zu tun, was Sie wollen (obwohl ich habe es nicht ausprobiert).

Kairo kann SVG nicht macht aus dem Kasten heraus. Es scheint, wir haben librsvg verwenden.

gefunden Gerade diese beiden Seiten:

So etwas sollte wahrscheinlich funktionieren (machen test.svg test.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")

Der letzte Kommentar abgestürzt, als ich es lief, weil svg.render_cairo () einen kairo Kontext und keine kairo Oberfläche erwartet. Ich habe und getestet, um die folgende Funktion und es scheint, auf meinem System laufen zu lassen.

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

Auf der Grundlage von anderen Antworten, hier ist eine Funktion, um eine SVG-Datei in ein pygame Bild zu lesen - einschließlich Korrektur Farbkanal Ordnung und Skalierung:

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
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top