Python: SVG to PNG converting issue

Viewed 1144

UPDATE: I tried increasing size in the chess.svg.board and it somehow cleared all the rendering issues at size = 900 1800

I tried using the svglib and reportlab to make .png files from .svg, and here is how the code looks:

import sys
import chess.svg
import chess
from svglib.svglib import svg2rlg
from reportlab.graphics import renderPM

board = chess.Board("rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR")

drawing = chess.svg.board(board, size=350)
f = open('file.svg', 'w')
f.write(drawing)

drawing = svg2rlg("file.svg")
renderPM.drawToFile(drawing, "file.png", fmt="png")

If you try to open file.png there is a lot of missing parts of the image, which i guess are rendering issues. How can you fix this?

Sidenote: also getting a lot of 'x_order_2: colinear!' messages when running this on a discord bot, but I am not sure if this affects anything yet. enter image description here

2 Answers

THIS!! I am having the same error with the same libraries... I didn't find a solution but just a workaround which probably won't help too much in your case, where the shapes generating the bands are not very sparse vertically.

I'll try playing with the file dimensions too, but so far this is what I got. Note that my svg consists of black shapes on a white background (hence the 255 - x in the following code)

Since the appearance of the bands is extremely random, and processing the same file several times in a row produces different results, I decided to take advantage of randomness: what I do is I export the same svg a few times into different pngs, import them all into a list and then only take those pixels that are white in all the exported images, something like:

images_files = [my_convert_function(svgfile=file, index=i) for i in range(3)]
images = [255 - imageio.imread(x) for x in images_files]
result = reduce(lambda a,b: a & b, images)
imageio.imwrite(<your filename here>, result)
[os.remove(x) for x in images_files]

where my_convert_function contains your same svg2rlg and renderPM.drawToFile, and returns the name of the png file being written. The index 'i' is to save several copies of the same png with different names.

It's some very crude code but I hope it can help other people with the same issue

The format parameter has to be in uppercase

renderPM.drawToFile(drawing, "file.png", fmt="PNG")
Related