使用Python Pillow将PNG图像转字节后读取时如何保留色彩?
用Pillow读取PNG字节数据并保留色彩的解决方案
问题根源
你用img.tobytes()拿到的只是原始像素值,但PNG的P(调色板)模式需要配套的调色板信息才能解析颜色。frombytes只传像素数据的话,没有调色板映射,自然读不出正确色彩,只会得到黑块或失真图。
可行解决方法
1. 保留调色板信息读取
转字节时同时保存调色板,读取时把调色板加回去:
from PIL import Image # 保存像素数据+调色板 img = Image.open(image_path) pixel_data = img.tobytes() palette = img.getpalette() # 还原图像 if img.mode == 'P': new_img = Image.frombytes('P', img.size, pixel_data) new_img.putpalette(palette) # 按需转成RGB模式方便后续操作 new_img = new_img.convert('RGB')
2. 转RGB模式后再处理
如果不需要保留调色板格式,直接先转成RGB模式再生成字节,读取时就不会有色彩问题:
from PIL import Image # 转RGB后生成字节 img = Image.open(image_path).convert('RGB') pixel_data = img.tobytes() # 读取还原 new_img = Image.frombytes('RGB', img.size, pixel_data)
3. 用BytesIO处理完整PNG字节流
如果只是为了旋转图像,没必要手动拆像素,直接保存完整的PNG文件字节流,读取后再操作更省心:
from PIL import Image from io import BytesIO # 生成完整PNG字节流 img = Image.open(image_path) buf = BytesIO() img.save(buf, format='PNG') buf.seek(0) png_byte_data = buf.getvalue() # 读取并旋转 rotated_img = Image.open(BytesIO(png_byte_data)).rotate(90)
注意事项
P模式图像必须同时保存像素数据和调色板,缺一不可tobytes()只输出像素值,不包含图像格式、调色板这类元数据- 优先用BytesIO处理完整字节流,避免手动解析像素的繁琐步骤
内容的提问来源于stack exchange,提问作者AAlvz
相关产品推荐
相关产品推荐

