如何用Pillow将Keil生成的1字节RGB数据转为256色PNG?
大学项目:从Keil处理后的1字节RGB Hex文件生成256色PNG
需求说明
- 在Keil环境中完成格式转换:将4字节RGBA格式PNG转为1字节RGB格式,字节结构为
RRR_GGG_BB(R取最高3位、G取最高3位、B取最高2位,丢弃Alpha通道) - 转换后输出含1字节RGB数据的Hex文件,需用Python的Pillow库将该Hex文件还原为256色PNG
最初尝试的问题
直接使用Image.fromarray()加载索引数组无法正确生成图片,代码如下:
from intelhex import IntelHex from PIL import Image import numpy as np ih = IntelHex() ih.loadhex('memoutput.hex') pydict=ih.todict() rgbcomp = np.fromiter(pydict.values(), dtype=int) rgbcomp = np.reshape(rgbcomp,(640,960)) img_2 = Image.fromarray(rgbcomp, 'P') img_2.show()
解决方案与完整代码
核心步骤是手动生成调色板(将1字节RGB映射为标准24位RGB)和像素索引数组(每个像素值对应调色板中的索引),再通过Pillow的API生成图片。完整代码:
from intelhex import IntelHex from PIL import Image import numpy as np # 加载Hex文件并提取像素数据 ih = IntelHex() ih.loadhex('memoutput.hex') pydict = ih.todict() rgbcomp = np.fromiter(pydict.values(), dtype=int) # 获取所有唯一的1字节RGB值,用于生成调色板 uniqRgbComp = np.unique(rgbcomp) # 生成调色板:将1字节RRRGGGBB格式转换为24位RGB plte = np.zeros((len(uniqRgbComp), 3)) for i in range(len(uniqRgbComp)): # 拆分各分量并补全为8位 r = uniqRgbComp[i] & 0b11100000 # 取高3位,保留原位置 g = (uniqRgbComp[i] & 0b00011100) << 3 # 取中间3位,左移3位补全8位 b = (uniqRgbComp[i] & 0b00000011) << 6 # 取低2位,左移6位补全8位 plte[i] = np.array([r, g, b]) # 生成像素索引数组:每个像素值对应调色板中的索引位置 pltePix = np.zeros(len(rgbcomp)) for i in range(len(rgbcomp)): pltePix[i] = np.argwhere(uniqRgbComp == rgbcomp[i])[0] # 调整数组形状并创建256色图片 pltePix = np.reshape(pltePix, (640, 960)) im = Image.new(mode="P", size=(960, 640)) # 加载调色板和像素数据 plte = np.ravel(plte).astype(np.uint8).tolist() im.putpalette(plte, rawmode="RGB") im.putdata(pltePix.astype(np.uint8)) im.show()
效果对比
原始图片

目标参考效果

最终输出图片

内容的提问来源于stack exchange,提问作者hojin3777
相关产品推荐
相关产品推荐

