You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 11:47:32