You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何python-chess生成的带棋子SVG在Pygame中仅显示空棋盘?

Pygame加载chess.svg生成的SVG文件时不显示棋子的问题解决

问题描述

使用Pygame与python-chess开发国际象棋游戏时,出现异常:代码生成的SVG文件手动打开能正常显示带棋子的棋盘,但通过Pygame的blit方法加载该文件时,窗口仅显示空棋盘。已确认不是通用SVG加载问题,可正常加载其他SVG文件,疑惑同一文件为何无法显示棋子。

代码示例

import pygame as pg
import chess
import chess.svg
import chess.pgn

WIDTH, HEIGHT = 900, 500
WINDOW = pg.display.set_mode((WIDTH,HEIGHT))
pg.display.set_caption('Opening mastery')
FPS = 60

board = chess.BaseBoard()

def get_board_img(brd):
    SVG = chess.svg.board(board=brd)
    f = open("image.svg", "w")
    f.write(SVG)
    f.close()
    image = ('image.svg')
    return image

def main():
    clock = pg.time.Clock()
    run = True
    while run:
        clock.tick(FPS)
        for event in pg.event.get():
            if event.type == pg.QUIT:
                run = False
        image = get_board_img(board)
        WINDOW.blit(pg.image.load(image),(0,0))
        pg.display.update()
        
    pg.quit()
if __name__ == '__main__':
    main()

效果对比

  • 手动打开SVG文件效果(显示棋子):
    手动打开SVG显示完整棋盘

  • Pygame运行效果(仅空棋盘):
    Pygame加载后显示空棋盘

问题原因

chess.svg生成的SVG文件中,棋子图形是通过外部SVG资源引用实现的(比如引用了库内置的棋子SVG文件路径)。而Pygame的pg.image.load()方法加载SVG时,并不支持解析外部引用的资源,只会渲染SVG文件内的本地图形元素,导致棋子无法被加载显示。

解决方案

最简便的解决方法是将SVG文件转换为Pygame完全支持的位图格式(如PNG),确保所有元素(包括棋子)都被预渲染到位图中。这里使用cairosvg库完成转换:

步骤1:安装依赖库

pip install cairosvg

步骤2:修改代码

import pygame as pg
import chess
import chess.svg
import cairosvg
from io import BytesIO

WIDTH, HEIGHT = 900, 500
WINDOW = pg.display.set_mode((WIDTH,HEIGHT))
pg.display.set_caption('Opening mastery')
FPS = 60

board = chess.BaseBoard()

def get_board_img(brd):
    # 生成棋盘SVG数据
    svg_data = chess.svg.board(board=brd)
    # 将SVG转换为PNG字节流
    png_bytes = cairosvg.svg2png(bytestring=svg_data.encode('utf-8'))
    # 从字节流加载为Pygame Surface对象
    return pg.image.load(BytesIO(png_bytes))

def main():
    clock = pg.time.Clock()
    run = True
    while run:
        clock.tick(FPS)
        for event in pg.event.get():
            if event.type == pg.QUIT:
                run = False
        board_surface = get_board_img(board)
        WINDOW.blit(board_surface, (0, 0))
        pg.display.update()
        
    pg.quit()
if __name__ == '__main__':
    main()

方案说明

cairosvg会完整解析SVG中的所有元素(包括外部引用的棋子资源),将其渲染为完整的PNG图像,再通过字节流直接加载到Pygame中,避免了外部资源引用的问题,确保棋盘和棋子都能正常显示。

内容的提问来源于stack exchange,提问作者Rey Fit

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 17:16:08