微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

在 Python Pygame 上显示 SVG来自字符串

如何解决在 Python Pygame 上显示 SVG来自字符串

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

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>'

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

其伪代码应该类似于

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

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

的实现

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

from SOME_LIBRARY import SOME_COMPONENT

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

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

Display SVG file in Python 中给出的解决方案似乎不符合要求,因为它在 PyGame 中不起作用。如果有人可以让它工作,请告诉我。

解决方法

如何阅读 Scalable Vector Graphics (SVG) 文件已在 SVG rendering in a PyGame application 处解答。
渲染 SVG 字符串有多种可能性。

一个简单的可能性是使用 svglib。安装svglib

pip install svglib

编写一个函数来解析和光栅化一个 SVG 字符串并创建一个 pygame.Surface 对象:

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)

但是,透明背景似乎存在问题。有关于此主题 How to make the png background transparent? #171 的问题。

另一种解决方案(显然较慢)是使用 CairoSVG。使用函数cairosvg.svg2png,可以将Vector Graphics (SVG)文件直接转换为[便携式网络图形(PNG)]文件

安装 CairoSVG

pip install CairoSVG

编写一个将 SVF 文件转换为 PNG (ByteIO) 并创建一个 pygame.Surface 对象的函数可能如下所示:

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)

另见svgsurf.py^


最小示例:

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()

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。