Pygame 应用程序中的 SVG 渲染。 在 Pygame 2.0 之前,Pygame 不支持 SVG。 那你是怎么加载的呢?
In a Pygame application, I would like to render resolution-free GUI widgets described in SVG.
How can I achieve this?
(I like the OCEMP GUI toolkit, but it seems to be bitmap-dependent for its rendering.)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(10)
这是一个完整的例子,结合了其他人的提示。
它应该从当前目录渲染一个名为 test.svg 的文件。 它在 Ubuntu 10.10、python-cairo 1.8.8、python-pygame 1.9.1、python-rsvg 2.30.0 上进行了测试。
This is a complete example which combines hints by other people here.
It should render a file called test.svg from the current directory. It was tested on Ubuntu 10.10, python-cairo 1.8.8, python-pygame 1.9.1, python-rsvg 2.30.0.
Pygame 2.0 版支持 SVG 文件。 自版本 2.0.2 起,SDL Image 支持 SVG (可缩放矢量图形) 文件(请参阅SDL_image 2.0)。 因此,在 pygame 版本 2.0.1 中,SVG 文件可以加载到
pygame 中。使用
:pygame.image.load() 表面
对象在 Pygame 2 之前,您必须实现可缩放矢量图形加载与其他图书馆。 以下是有关如何执行此操作的一些想法。
一个非常简单的解决方案是使用 CairoSVG。 使用函数
cairosvg.svg2png
,矢量图形 (SVG) 文件可以直接转换为[便携式网络图形(PNG)]文件安装CairoSVG。
编写一个将 SVF 文件转换为 PNG 的函数 (
ByteIO
< /a>)并创建一个pygame.Surface
对象可能如下所示:另请参阅 加载 SVG< /a>
另一种方法是使用svglib。 但是,透明背景似乎存在问题。 关于此主题有一个问题 如何使 png 背景透明? #171.
安装svglib。
解析和光栅化 SVG 文件并创建
pygame.Surface
对象可能如下所示:另一个简单的解决方案是使用pynanosvg。 该解决方案的缺点是 Nanosvg 不再受到积极支持,并且无法与 Python 3.9 一起使用。 pynanosvg 可用于加载和光栅化矢量图形 (SVG) 文件。 安装 Cython 和 pynanosvg:
SVG 文件可以被读取、光栅化并加载到
pygame.Surface
对象具有以下功能:最小示例:
SVG files are supported with Pygame Version 2.0. Since Version 2.0.2, SDL Image supports SVG (Scalable Vector Graphics) files (see SDL_image 2.0). Therefore, with pygame version 2.0.1, SVG files can be loaded into a
pygame.Surface
object withpygame.image.load()
:Before Pygame 2, you had to implement Scalable Vector Graphics loading with other libraries. Below are some ideas on how to do this.
A very simple solution is to use CairoSVG. With the function
cairosvg.svg2png
, an Vector Graphics (SVG) files can be directly converted to an [Portable Network Graphics (PNG)] fileInstall CairoSVG.
Write a function that converts a SVF file to a PNG (
ByteIO
) and creates apygame.Surface
object may look as follows:See also Load SVG
An alternative is to use svglib. 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.
Install svglib.
A function that parses and rasterizes an SVG file and creates a
pygame.Surface
object may look as follows:Anther simple solution is to use pynanosvg. The downside of this solution is that nanosvg is no longer actively supported and does not work with Python 3.9. pynanosvg can be used to load and rasterize Vector Graphics (SVG) files. Install Cython and pynanosvg:
The SVG file can be read, rasterized and loaded into a
pygame.Surface
object with the following function:Minimal example:
有一种新的可能性可以工作,并且不再需要
librsvg
。 有 nanosvg 库上的 Cython 包装器 并且它有效:我发现 Cairo/rsvg 解决方案太复杂而无法获得由于依赖项的安装非常困难,所以无法正常工作。
There is a new possibility that works and does not require
librsvg
anymore. There is the Cython wrapper over nanosvg library and it works:I found Cairo/rsvg solution too complicated to get to work because of dependencies are quite obscure to install.
您可以使用 Cairo (与 PyCairo 一起),它支持渲染 SVG。 PyGame 网页有一个 HOWTO,用于使用 Cairo 渲染到缓冲区,并直接使用该缓冲区PyGame。
You can use Cairo (with PyCairo), which has support for rendering SVGs. The PyGame webpage has a HOWTO for rendering into a buffer with a Cairo, and using that buffer directly with PyGame.
我意识到这并不能完全回答你的问题,但是有一个名为 Squirtle 的库可以使用 Pyglet 或 PyOpenGL 渲染 SVG 文件。
I realise this doesn't exactly answer your question, but there's a library called Squirtle that will render SVG files using either Pyglet or PyOpenGL.
Cairo 无法直接呈现 SVG。
看来我们必须使用librsvg。
我刚刚找到了这两页:
像这样的东西可能应该有效(渲染 test.svg 到test.png):
Cairo cannot render SVG out of the box.
It seems we have to use librsvg.
I just found those two pages:
Something like this should probably work (render test.svg to test.png):
pygamesvg 似乎可以做你想做的事情(尽管我还没有尝试过)。
pygamesvg seems to do what you want (though I haven't tried it).
当我运行它时,最后一条评论崩溃了,因为 svg.render_cairo() 期望的是 Cairo 上下文而不是开罗表面。 我创建并测试了以下函数,它似乎在我的系统上运行良好。
The last comment crashed when I ran it because svg.render_cairo() is expecting a Cairo context and not a Cairo surface. I created and tested the following function and it seems to run fine on my system.
尽管 Pygame/SDL 对 SVG 文件的新支持,其渲染功能仍然非常有限,因此可能仍然需要 LibRsvg。 这是已接受答案的 2022 年更新,适用于现代版本的 Python、Pygame 和 Pycairo:
Despite Pygame/SDL new support for SVG files, its rendering features are still very limited, so LibRsvg might still be needed. This is a 2022 update for the accepted answer that works with modern versions of Python, Pygame and Pycairo:
基于其他答案,这里有一个将 SVG 文件读入 Pygame 图像的函数,包括纠正颜色通道顺序和缩放:
Based on other answers, here's a function to read a SVG file into a Pygame image—including correcting color channel order and scaling: