2

I'm trying to make a chess opening trainer with Pygame. Graphically, it's incredibly simple; it works like a slideshow, I am only blitting a single image to the screen at a time which updates when I press the return key. I am using chess.svg to generate an SVG of the current game state. Not being able to use SVGs natively with pygame means that I have been converting the SVG to a PNG.

Viewing the PNG on my computer, it's very clear.

PNG Image

However when pygame displays the image, it's very blurry.

Pygame Image

Ideally I would like pygame to display the SVG so I don't have to worry about the resolution at all. All I found on pygame and SVGs was this link from 12 years ago. In 2018, an answer was posted stating that the original methods no longer worked. However, now, in 2021 the methods given in 2018 no longer work either; I tried, and one comment also confirms this.

If using SVGs is not possible, that's fine, provided I can get pygame to display the PNG at a greater definition than it currently does.

Even if I make screen = pygame.display.set_mode((width, height)) fullscreen, it's still blurry. I can't seem to find anything on that, so I'm not sure that's the issue here.

Here's a simplified version of my code to demonstrate the graphical part:

import pygame
from pygame.locals import *
import chess
import cairosvg
import chess.svg
import chess.pgn

##Setup Pygame:
pygame.init()
 
width, height = 640, 640
screen = pygame.display.set_mode((width, height))

## MAIN ##

board = chess.Board()
                
#Step 1: Create image
boardsvg = chess.svg.board(board=board)
f = open("image.SVG", "w")
f.write(boardsvg)
f.close()

#scale
cairosvg.svg2png(url="image.svg", write_to="image_scaled.png", scale=3.0)

#Step2: Blit the image
image = pygame.image.load('image_scaled.png')
image = pygame.transform.scale(image, (640, 640))
screen.blit(image,(0,0))
pygame.display.flip()

Does anyone one know what I need to try?

Cheers.

  • 1
    The likend question has new answers (From 2020). Hence the information there is not outdated. See [SVG rendering in a PyGame application](https://stackoverflow.com/questions/120584/svg-rendering-in-a-pygame-application/64598021#64598021). – Rabbid76 Apr 13 '21 at 16:49
  • 1
    What it the resolution of the PNG? Do you scale it down?. When you downscale an image, it may become blurry. – Rabbid76 Apr 13 '21 at 16:59
  • What is the size of the original svg file generated and from what it seems like the blurryness might be a result of scaling and rescaling of the image, since you first rescale it by 3 times and then you rescale it to the resolution (640, 640) – typedecker May 06 '21 at 07:56

3 Answers3

1

I found that using smoothscale like so image = pygame.transform.smoothscale(image, (width, height)) helped a little, but it still wasn't perfect. In the end I decided to rewrite it in javascript using cm-chessboard.

1

chess.svg.board has a size keyword argument:

size – The size of the image in pixels (e.g., 400 for a 400 by 400 board), or None (the default) for no size limit.

e.g.

boardsvg = chess.svg.board(board=board, size=1024)

Setting this to your output size should fix the blurryness.

2080
  • 1,223
  • 1
  • 14
  • 37
0

In 2021 you can use Pygame 2 + SDL2, which loads SVG images directly, no need of cairo or any other lib:

import io
import pygame
from pygame.locals import *
import chess
import chess.svg

##Setup Pygame:
pygame.init()
 
width, height = 640, 640
screen = pygame.display.set_mode((width, height))

## MAIN ##

board = chess.Board()
                
#Step 1: Create image
boardsvg = io.BytesIO(chess.svg.board(board=board).encode())

#Step 2: Blit the image
image = pygame.image.load(boardsvg)
image = pygame.transform.scale(image, (640, 640))
screen.blit(image,(0,0))
pygame.display.flip()
MestreLion
  • 12,698
  • 8
  • 66
  • 57