简体   繁体   English

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

[英]Display SVG (from string) on Python Pygame

I have an SVG graphic represented in a string我有一个用字符串表示的 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>'

I want to display the graphics represented by svg_string , which is 2 ellipses, on a window initiated from Python.我想在从 Python 启动的 window 上显示由svg_string表示的图形,它是 2 个椭圆。

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)我基本上正在查看方法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我也愿意使用非 pygame 库,只要它遵循以下简单接口并且可以将其包含在 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.我已经看过pynanosvg但它不再受支持并且失败了所以不能满足我的需要。

The solution given in Display SVG file in Python does not seem to fit the bill as it is not working in PyGame.在 Python 中的Display SVG 文件中给出的解决方案似乎不符合要求,因为它在 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 . 在 PyGame 应用程序中的 SVG 渲染中回答了如何读取可缩放矢量图形 (SVG)文件。
There are multiple possibilities to render a SVG string.呈现 SVG 字符串有多种可能性。

A simple possibility is to use svglib .一个简单的可能性是使用svglib Install svglib :安装svglib

pip install svglib

Write a function that parses and rasterizes an SVG string and and creates a pygame.Surface object:编写一个 function 来解析和光栅化 SVG 字符串并创建一个pygame.Surface ZCD15A75C2600869647B31A3F0DE43B3Z

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?关于这个主题有一个问题如何使png背景透明? #171 .第171章

An alternative solution (which is apparently slower) is to use CairoSVG .另一种解决方案(显然更慢)是使用CairoSVG With the function cairosvg.svg2png , an Vector Graphics (SVG) files can be directly converted to an [Portable Network Graphics (PNG)] file使用 function cairosvg.svg2png ,可以将矢量图形 (SVG)文件直接转换为 [便携式网络图形 (PNG)] 文件

Install CairoSVG .安装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:编写 function 将 SVF 文件转换为 PNG ( ByteIO ) 并创建pygame.Surface 。表面 object 可能如下所示:

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 .另请参见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()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM