PyGameExamplesAndAnswers

StackOverflow            reply.it reply.it

“The first principle is that you must not fool yourself and you are the easiest person to fool.”
Richard P. Feynman


Surface and image, load SVG

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

Legacy SVG loading

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)