pygame.image.fromstring()参数报错 PIL灰度图转Surface失败
报错原因
pygame.image.fromstring原生不支持PIL库L模式(8位单通道灰度)的图像格式,直接传入"L"作为格式参数会触发ValueError: Unrecognized type of format报错。传入"P"参数显示异常是因为P是PIL的调色板索引模式,和单通道灰度的存储逻辑不匹配,因此会输出纯灰色块。- 原测试代码存在变量名笔误:转换得到的Surface对象赋值给了
pygameimage,后续blit调用时误写为pygame_image,会触发变量未定义错误。
修复方法
优先使用兼容性最好的方案:转换前先将PIL灰度图转为pygame原生支持的RGB模式,不会出现色彩显示偏差,转换函数修改如下:
def pilImageToSurface(pilImage): # 灰度图提前转RGB适配pygame格式要求 if pilImage.mode == 'L': pilImage = pilImage.convert('RGB') return pygame.image.fromstring( pilImage.tobytes(), pilImage.size, pilImage.mode )
如果需要更高的转换性能,可以跳过PIL转格式步骤,直接基于numpy数组生成Surface,注意调整轴顺序匹配pygame的坐标规则:
def numpyGrayToSurface(gray_arr): # 单通道灰度数组扩展为三通道RGB rgb_arr = np.repeat(gray_arr[..., None], 3, axis=2) # surfarray默认轴顺序为(宽, 高),和numpy数组(高, 宽)的顺序互换 return pygame.surfarray.make_surface(rgb_arr.swapaxes(0, 1))
替换原代码中的转换函数、修正变量名笔误,补充窗口保活逻辑后,完整可运行代码如下:
import numpy as np from PIL import Image import pygame pygame.init() white = (255, 255, 255) X = 1920 Y = 1080 display_surface = pygame.display.set_mode((X, Y)) pygame.display.set_caption('Image') display_surface.fill(white) # 生成测试灰度图 imagelist = ((0,1,2,3),(255,254,253,252),(100,101,102,103)) imagearray = np.array(imagelist, dtype=np.uint8) imagedata = Image.fromarray(imagearray) def pilImageToSurface(pilImage): if pilImage.mode == 'L': pilImage = pilImage.convert('RGB') return pygame.image.fromstring( pilImage.tobytes(), pilImage.size, pilImage.mode ) pygameimage = pilImageToSurface(imagedata) # 修正原变量名笔误 display_surface.blit(pygameimage, (0, 0)) pygame.display.update() # 事件循环防止窗口立即退出 running = True while running: for event in pygame.event.get(): if event.type == pygame.QUIT: running = False pygame.quit()
运行后即可正常显示灰度图像内容。
内容的提问来源于stack exchange,提问作者JBowers
相关产品推荐
相关产品推荐

