Python中SVG转BMP报错求助:wx.App未创建及PNG格式问题
解决SVG转BMP的两个问题(CairoSVG + wxPython错误)
先帮你拆解下遇到的两个核心问题,再给出可行的修复方案:
问题1:"This is not a PNG file"
你调用cairosvg.svg2png(url="test.svg", write_to="test.png")时,这个函数不会返回PNG字节数据——当指定了write_to参数,它只会把PNG直接写入你指定的文件,所以png变量实际是None。之后用io.StringIO(png)读取无效数据,自然会触发“不是PNG文件”的错误。
如果想在内存中处理PNG,要去掉write_to参数,让函数返回字节数据,并且用io.BytesIO(PNG是二进制文件,不能用文本型的StringIO)来包装。
问题2:wx._core.PyNoAppError
wxPython的所有图像操作都依赖wx.App实例的存在,必须先创建并初始化App对象,才能使用wx.Image和wx.Bitmap——哪怕你不需要显示任何窗口,这一步也不能省。
修正后的wxPython版本代码
下面是修复后的完整代码,能解决两个错误并生成目标BMP文件:
import cairosvg import wx import io # 先创建wx.App实例,必须放在所有wx操作之前 app = wx.App(False) # False表示不需要重定向标准输出/错误 # 将SVG转为内存中的PNG字节数据(不写入本地文件) png_bytes = cairosvg.svg2png(url="test.svg") # 用BytesIO包装二进制数据供wx.Image读取 png_io = io.BytesIO(png_bytes) # 加载PNG并保存为BMP img = wx.Image(png_io, wx.BITMAP_TYPE_PNG) img.SaveFile("test.bmp", wx.BITMAP_TYPE_BMP) # 无需窗口时直接退出App app.Exit()
更轻量的替代方案:用Pillow库
如果你的需求只是格式转换(不需要wx的UI功能),用Pillow库会更简单,完全不用处理App初始化的麻烦。安装Pillow和cairosvg后,代码更简洁:
import cairosvg from PIL import Image import io # SVG转PNG字节数据 png_bytes = cairosvg.svg2png(url="test.svg") # 用Pillow加载PNG并直接保存为BMP with Image.open(io.BytesIO(png_bytes)) as img: img.save("test.bmp", format="BMP")
这个方案更适配你的场景——纯粹做格式转换,生成的BMP完全可以直接传入potrace工具使用。
内容的提问来源于stack exchange,提问作者Slava Maradudin




