在 Python Pygame 上显示 SVG(来自字符串) [英] Display SVG (from string) on Python Pygame

查看:73
本文介绍了在 Python Pygame 上显示 SVG(来自字符串)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个用字符串表示的 SVG 图形

svg_string='

我想在 Python 启动的窗口上显示 svg_string 表示的图形,即 2 个椭圆.

其伪代码应该类似于

导入pygamedef display_svg_figure(屏幕,svg_string):# 绘制渲染的 SVG 字符串的代码#   屏幕经过背景颜色 = (255, 255, 255)(宽, 高) = (900, 900)screen = pygame.display.set_mode((width, height))pygame.display.set_caption('显示SVG')screen.fill(background_colour)pygame.display.flip()svg_string='<svg height="100";宽度=500"><椭圆cx=240"cy=50"rx=220"ry=30"样式=填充:黄色"/><ellipse cx=220"cy=50"rx=190"ry=20"样式=填充:白色"/></svg>'display_svg_figure(屏幕,svg_string)运行 = 真在跑步的时候:对于 pygame.event.get() 中的事件:如果 event.type == pygame.QUIT:运行 = 错误

我基本上是在看方法 display_svg_figure(screen,svg_string)

的实现

我对使用非 pygame 库也持开放态度,只要它遵循以下简单接口并且可以将其包含在 pygame 中

from SOME_LIBRARY import SOME_COMPONENTsvg_string =......"SOME_COMPONENT.display(svg_string)

我已经看过 pynanosvg 但它不再受支持并且失败了,所以不能满足我的需要.

from svglib.svglib import svg2rlg导入pygame导入 iodef load_svg_svglib(svg_string):svg_io = io.StringIO(svg_string)绘图 = svg2rlg(svg_io)str = drawing.asString("png")byte_io = io.BytesIO(str)svg_surf = pygame.image.load(byte_io)返回 svg_surfdef display_svg_figure(屏幕,svg_string):冲浪 = load_svg_svglib(svg_string)screen.blit(冲浪, (0, 0))背景颜色 = (255, 255, 255)(宽, 高) = (900, 900)screen = pygame.display.set_mode((width, height))pygame.display.set_caption('显示SVG')screen.fill(background_colour)svg_string='<svg height="100";宽度=500"><椭圆cx=240"cy=50"rx=220"ry=30"样式=填充:黄色"/><ellipse cx=220"cy=50"rx=190"ry=20"样式=填充:白色"/></svg>'display_svg_figure(屏幕,svg_string)运行 = 真在跑步的时候:对于 pygame.event.get() 中的事件:如果 event.type == pygame.QUIT:运行 = 错误pygame.display.flip()

I have an SVG graphic represented in a string

svg_string='<svg height="100" width="500"><ellipse cx="240" cy="50" rx="220" ry="30" style="fill:yellow" /><ellipse cx="220" cy="50" rx="190" ry="20" style="fill:white" /></svg>'

I want to display the graphics represented by svg_string, which is 2 ellipses, on a window initiated from Python.

The pseudo code of which should be something like

import pygame


def display_svg_figure(screen, svg_string):
    #   Code that draws the rendered SVG string on
    #   the screen
    pass

background_colour = (255, 255, 255)
(width, height) = (900, 900)

screen = pygame.display.set_mode((width, height))
pygame.display.set_caption('Display SVG')
screen.fill(background_colour)

pygame.display.flip()

svg_string='<svg height="100" width="500"><ellipse cx="240" cy="50" rx="220" ry="30" style="fill:yellow" /><ellipse cx="220" cy="50" rx="190" ry="20" style="fill:white" /></svg>'
display_svg_figure(screen, svg_string)


running = True
while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False

I am basically looking at an implementation of the method display_svg_figure(screen,svg_string)

I am open to a using non pygame libraries too as long as it follows the simple interfaces of the following and is possible to include it in pygame

from SOME_LIBRARY import SOME_COMPONENT

svg_string="......"
SOME_COMPONENT.display(svg_string)

I have already looked at pynanosvg but that's no longer supported and is failing so does not suffice my need.

The solution given in Display SVG file in Python does not seem to fit the bill as it is not working in PyGame. If someone can make it work kindly let me know.

解决方案

How to read an Scalable Vector Graphics (SVG) file is answered at SVG rendering in a PyGame application.
There are multiple possibilities to render a SVG string.

A simple possibility is to use svglib. Install svglib:

pip install svglib

Write a function that parses and rasterizes an SVG string and and creates a pygame.Surface object:

from svglib.svglib import svg2rlg
import io

def load_svg(svg_string):
    svg_io = io.StringIO(svg_string)
    drawing = svg2rlg(svg_io)
    str = drawing.asString("png")
    byte_io = io.BytesIO(str)
    return pygame.image.load(byte_io)

However, there seems to be a problem with transparent backgrounds. There is an issue about this topic How to make the png background transparent? #171.

An alternative solution (which is apparently slower) is to use CairoSVG. With the function cairosvg.svg2png, an Vector Graphics (SVG) files can be directly converted to an [Portable Network Graphics (PNG)] file

Install CairoSVG.

pip install CairoSVG

Write a function that converts a SVF file to a PNG (ByteIO) and creates a pygame.Surface object may look as follows:

import cairosvg
import io

def load_svg(filename):
    new_bites = cairosvg.svg2png(url = filename)
    byte_io = io.BytesIO(new_bites)
    return pygame.image.load(byte_io)

See also svgsurf.py.


Minimal example:

from svglib.svglib import svg2rlg
import pygame
import io

def load_svg_svglib(svg_string):
    svg_io = io.StringIO(svg_string)
    drawing = svg2rlg(svg_io)
    str = drawing.asString("png")
    byte_io = io.BytesIO(str)
    svg_surf = pygame.image.load(byte_io)
    return svg_surf

def display_svg_figure(screen, svg_string):
    surf = load_svg_svglib(svg_string)
    screen.blit(surf, (0, 0))

background_colour = (255, 255, 255)
(width, height) = (900, 900)

screen = pygame.display.set_mode((width, height))
pygame.display.set_caption('Display SVG')
screen.fill(background_colour)

svg_string='<svg height="100" width="500"><ellipse cx="240" cy="50" rx="220" ry="30" style="fill:yellow" /><ellipse cx="220" cy="50" rx="190" ry="20" style="fill:white" /></svg>'
display_svg_figure(screen, svg_string)

running = True
while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False

    pygame.display.flip()

这篇关于在 Python Pygame 上显示 SVG(来自字符串)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆