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

使用Python2+PIL将PNG转为Bootloader用BIN文件失败,求代码修复

修复PNG转Bootloader BIN文件的Python2代码

原代码存在多个关键问题导致转换失败,以下是修复后的完整代码及说明:

import math
import sys
from PIL import Image

doscolors = [
    (0x00, 0x00, 0x00), # 0
    (0x00, 0x00, 0xa8), # 1
    (0x00, 0xa8, 0x00), # 2
    (0x00, 0xa8, 0xa8), # 3
    (0xa8, 0x00, 0x00), # 4
    (0xa8, 0x00, 0xa8), # 5
    (0xa8, 0xa8, 0x00), # 6
    (0xa8, 0xa8, 0xa8), # 7
    
    (0x54, 0x54, 0x54), # 8
    (0x54, 0x54, 0xff), # 9
    (0x54, 0xff, 0x54), # 10
    (0x54, 0xff, 0xff), # 11
    (0xff, 0x54, 0x54), # 12
    (0xff, 0x54, 0xff), # 13
    (0xff, 0xff, 0x54), # 14
    (0xff, 0xff, 0xff), # 15
]

def color_distance(a, b):
    # 去掉平方根计算,比较平方值即可,提升效率
    return (a[0]-b[0])**2 + (a[1]-b[1])**2 + (a[2]-b[2])**2
    
def nearest_color(color):
    nearest_idx = 0
    min_dist = color_distance(color, doscolors[0])
    
    for i in range(1, len(doscolors)):
        current_dist = color_distance(color, doscolors[i])
        if current_dist < min_dist:
            min_dist = current_dist
            nearest_idx = i
    
    return nearest_idx

def main():
    if len(sys.argv) < 3:
        print("用法: python script.py <输入PNG文件...> <输出BIN文件>")
        sys.exit(1)
    
    buf = []
    output_file = sys.argv[-1]
    
    for imgf in sys.argv[1:-1]:
        img = Image.open(imgf).convert("RGB")
        w, h = img.size
        
        # 确保图像高度为偶数,不足则补一行黑色像素
        if h % 2 != 0:
            new_img = Image.new("RGB", (w, h + 1), (0, 0, 0))
            new_img.paste(img, (0, 0))
            img = new_img
            w, h = img.size
        
        for y in xrange(0, h, 2):
            for x in xrange(w):
                # 获取上下两个像素的颜色索引
                top_idx = nearest_color(img.getpixel((x, y)))
                bottom_idx = nearest_color(img.getpixel((x, y + 1)))
                # 合并为一个字节(高4位上像素,低4位下像素)
                b = (top_idx << 4) | bottom_idx
                buf.append(chr(b))
        
        img.close()
    
    # 写入BIN文件
    with open(output_file, "wb") as out:
        out.write(''.join(buf))

if __name__ == "__main__":
    main()

关键修复点说明:

  • 补充缺失模块:添加import sys,原代码使用sys.argv但未导入该模块,会直接触发运行错误。
  • 参数合法性校验:添加命令行参数数量检查,避免因参数不足导致的索引越界问题。
  • 处理奇数高度图像:Bootloader的BIN格式要求每两个像素合并为一个字节,因此强制图像高度为偶数,若原图像高度为奇数则自动补一行黑色像素。
  • 优化颜色距离计算:去掉平方根运算,直接比较颜色距离的平方值,结果一致但大幅提升计算效率。
  • 优化颜色匹配逻辑:避免重复计算颜色距离,每个颜色仅计算一次,减少冗余运算。
  • 优化字节存储方式:用列表buf代替字符串拼接,Python2中列表追加操作比字符串拼接效率更高,尤其处理大图像时优势明显。
  • 代码结构规范化:封装为main函数,使代码逻辑更清晰,符合Python开发规范。

内容的提问来源于stack exchange,提问作者moongazer 07

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 04:18:16