“The first principle is that you must not fool yourself and you are the easiest person to fool.”
Richard P. Feynman
Scalable Vector Graphics (SVG)
Related Stack Overflow questions:
Since 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 with pygame.image.load()
:
SFV File:
surface = pygame.image.load('my.svg')
📁 Minimal example - Load Scalable Vector Graphics (SVG) file in PyGame
SVG binary string
pygame_surface = pygame.image.load(io.BytesIO(svg_string.encode()))
📁 Minimal example - Load Scalable Vector Graphics (SVG) string in PyGame
Scale SVG:
def load_and_scale_svg(filename, scale):
svg_string = open(filename, "rt").read()
start = svg_string.find('<svg')
if start > 0:
svg_string = svg_string[:start+4] + f' transform="scale({scale})"' + svg_string[start+4:]
return pygame.image.load(io.BytesIO(svg_string.encode()))
pygame_surface = load_and_scale_svg('my.svg', 0.5)
📁 Minimal example - Load and scale Scalable Vector Graphics (SVG) file in PyGame
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)] 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)
📁 Minimal example - Load Scalable Vector Graphics (SVG) in PyGame Surface (cairosvg)
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.
pip install svglib
A function that parses and rasterizes an SVG file and creates a pygame.Surface
object may look as follows:
def load_svg(filename):
drawing = svg2rlg(filename)
str = drawing.asString("png")
byte_io = io.BytesIO(str)
return pygame.image.load(byte_io)
📁 Minimal example - Load Scalable Vector Graphics (SVG) in PyGame Surface (svglib)
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:
pip install Cython
pip install pynanosvg
The SVG file can be read, rasterized and loaded into a pygame.Surface
object with the following function:
def load_svg(filename, scale=None, size=None, clip_from=None, fit_to=None, foramt='RGBA'):
svg = Parser.parse_file(filename)
scale = min((fit_to[0] / svg.width, fit_to[1] / svg.height)
if fit_to else ([scale if scale else 1] * 2))
width, height = size if size else (svg.width, svg.height)
surf_size = round(width * scale), round(height * scale)
buffer = Rasterizer().rasterize(svg, *surf_size, scale, *(clip_from if clip_from else 0, 0))
return pygame.image.frombuffer(buffer, surf_size, foramt)
📁 Minimal example - Load Scalable Vector Graphics (SVG) to PyGame Surface (pynanosvg)