使用PIL.Image保存BMP缩放图时存为灰度图,如何保存彩色图?
问题解决:PIL保存缩小后的BMP为彩色图而非灰度图
问题原因
你的原BMP文件大概率是索引彩色模式(mode='P'),这种模式下图像存储的是颜色索引值,而非直接的RGB像素数据,导致问题的核心逻辑:
- 使用
np.asarray(imgNEW)时,仅提取了索引数组,丢失了关键的调色板信息; - 后续
Image.fromarray会把索引值当作灰度值处理,即使调用convert('RGB')也只是将灰度值复制到RGB三个通道,最终保存的是灰度转的假RGB图; - 而
plt.imshow会自动套用默认调色板渲染,所以显示时看起来是彩色,但实际保存的文件并非真实彩色。
解决方案
方案1:直接用PIL对象操作(推荐,避免丢失调色板)
无需转numpy数组,直接在PIL图像对象上完成缩放和格式转换:
from PIL import Image # 打开原BMP ibmp = Image.open('E:/Project files/label1.bmp') # 计算缩小后的尺寸 new_width = round(ibmp.size[0] / 200) new_height = round(ibmp.size[1] / 200) # 缩放图像 imgNEW = ibmp.resize((new_width, new_height)) # 转RGB模式并保存 imgNEW.convert('RGB').save("E:/Project files/Outout/image_rgb.png")
方案2:必须用numpy处理时,保留调色板信息
如果业务需求需要转numpy数组处理,需手动处理调色板,将索引图转为真实RGB数组:
from PIL import Image import numpy as np ibmp = Image.open('E:/Project files/label1.bmp') new_width = round(ibmp.size[0] / 200) new_height = round(ibmp.size[1] / 200) imgNEW = ibmp.resize((new_width, new_height)) # 处理索引彩色图 if imgNEW.mode == 'P': # 直接将索引图转为RGB数组 img_rgb_array = np.array(imgNEW.convert('RGB')) else: img_rgb_array = np.asarray(imgNEW) # 转回Image对象并保存 image = Image.fromarray(img_rgb_array) image.save("E:/Project files/Outout/image_rgb.png")
验证步骤
可以在打开图像后先打印模式,确认是否为索引模式:
print(ibmp.mode) # 如果输出'P',则说明是索引彩色图
内容的提问来源于stack exchange,提问作者diana
相关产品推荐
相关产品推荐

