문제

안에 피그 게임 응용 프로그램, SVG에 설명 된 해상도가없는 GUI 위젯을 렌더링하고 싶습니다.

이 목표를 달성하기 위해 어떤 도구 및/또는 라이브러리를 사용할 수 있습니까?

(나는 좋아한다 OCEMP GUI 툴킷이지만 렌더링에 비트 맵 의존적 인 것 같습니다)

도움이 되었습니까?

해결책

이것은 여기 다른 사람들의 힌트를 결합한 완전한 예입니다. 현재 디렉토리에서 test.svg라는 파일을 렌더링해야합니다. 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

다른 팁

질문은 꽤 오래되었지만 10 년이 지났고 효과가 있고 필요하지 않은 새로운 가능성이 있습니다. librsvg 더 이상. 거기 있습니다 NANOSVG 라이브러리 위의 Cython 래퍼 그리고 그것은 작동합니다 :

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)

Cairo/RSVG 솔루션은 종속성 때문에 작업하기에 너무 복잡한 것을 발견했습니다.

당신이 사용할 수있는 카이로 (Pycairo와 함께) SVG 렌더링을 지원합니다. Pygame 웹 페이지에는 a가 있습니다 어떻게 카이로로 버퍼로 렌더링하고 Pygame과 함께 해당 버퍼를 사용합니다.

나는 이것이 당신의 질문에 정확히 대답하지 않는다는 것을 알고 있지만, 다람쥐 Pyglet 또는 Pyopengl을 사용하여 SVG 파일을 렌더링합니다.

pygamesvg 당신이 원하는 것을하는 것 같습니다 (내가 시도하지는 않았지만).

카이로는 SVG를 상자 밖으로 렌더링 할 수 없습니다. LIBSVG를 사용해야하는 것 같습니다.

방금 두 페이지를 찾았습니다.

이와 같은 것이 작동해야합니다 (렌더링 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")

svg.render_cairo ()가 카이로 표면이 아닌 카이로 컨텍스트를 기대하고 있기 때문에 마지막 주석이 추락했습니다. 다음 기능을 만들고 테스트했으며 시스템에서 잘 실행되는 것 같습니다.

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

다른 답변을 기반으로, 다음은 색상 채널 순서 수정 및 스케일링을 포함하여 SVG 파일을 Pygame 이미지로 읽는 기능입니다.

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
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top