将简单图像转换为Intel Hex格式

3
我正在为我的微处理器期末开发一款虚拟宠物(tamagotchi)。我制作了自己的图片,尺寸为128x64像素,因为我使用的显示器具有该分辨率,所以每个图像重量为1K字节。我使用的是at89s52(8052)微控制器,它没有足够的内存来存储所有我想要的动画。我的计划(我希望保持这种方式)是使用EPROM将所有我的图像保存为Intel Hex格式(我使用的编程器是SUPERPRO,它导入这种类型的文件)。当然,在我有ROM中的数据之后,汇编代码对我来说很容易。我不是一个能够开发出完全符合我的需求的代码的程序员(将图像转换为Intel Hex),而且我尝试过的所有软件都无法正确生成它们(例如:在空格中只应该有零,却插入了另一个值)。我已经尝试过使用透明背景、白色背景和jpg的png。我拥有的图片如下:http://imgur.com/a/yiCOb(似乎我不允许在此处发布图片)。我在互联网上找不到太多帮助,因此这个问题的答案将对未来基于MCU的程序员非常有帮助。谢谢。

不算名称不好,因为有Intel Hex和Motorola SRecord两种格式。如果你现在才听说它们,那么要么你是新手,要么这些格式比你还要老。自从EEPROM问世以来,EEPROM编程器就一直在使用其中一种文件格式,或者更可能是在Flash出现之前,当MCU还是EEPROM并需要插入编程器进行编程时,也需要相同的格式。 - old_timer
这个问题与汇编语言或微控制器无关,它只是关于如何从一些原始数据生成Intel Hex文件。据我所知,所有其他的问题等都与此无关。我不会说你的问题不清楚... - old_timer
@MargaretBloom 实际上,Intel Hex 是一个非常恰当的格式名称,它使用十六进制来表示数据,并来自 Intel 公司。实际上,Motorola S-Record 也不错,因为文件中的每个记录都以 S 开头,他们可能是 Intel 公司的竞争对手,所以不能称之为 Motorola Hex,这没有意义。Motorola S-Record 或其他名称都不太合适,但 Intel Hex 和 Motorola S-Record 都是非常好的、如果不是完美的文件格式名称。 - old_timer
@old_timer 抱歉,我想不出标签了,我想表达得清楚一些 :( - Neko
@old_timer 是的,我本来以为我得自己写代码来完成这个过程,因为我找不到相关资源和工具。而且我需要一个EPROM,因为我有超过50kb的图像,它们无法适应我的MCU :D - Neko
显示剩余5条评论
1个回答

4

距离我上一次制作EPROM已经大约30年了 :-)

无论如何,您需要2个东西...

第一部分

首先,您的文件是PNG格式,这意味着它们具有日期、时间、调色板、伽马块和一堆zlib压缩数据,您不能将其直接复制到屏幕缓冲区。因此,您需要将PNG转换为简单的二进制格式,其中0表示关闭,1表示开启,文件中没有其他内容。最简单的方法是使用在大多数Linux平台上安装的ImageMagick,并且在macOS和Windows上可以免费使用。假设您的一个帧被称为anim.png,我们想要将其转换为简单格式,比如PGM(便携式灰度图-请参见维基百科描述),我们可以在控制台上使用ImageMagick

convert anim.png -compress none anim.pgm

前几行将是:

P2
128 64
255
255 255 255 255 255 255 255 ...
...
...

因为该图像的大小为128x64,文件中的最大亮度值为255。然后所有数据都以ASCII格式跟随(因为我使用了-compress none)。在其中,255表示白色,0表示黑色。
由于这对于屏幕来说太大了,所以这里是一个图片,展示了它的外观 - 希望您能看到您的黑色方框在底部中间以一堆零的形式出现:

enter image description here

现在,如果您再次运行相同的命令,但删除-compress none,将产生相同的头部,但数据将以二进制形式跟随。
convert anim.png anim.pgm

我们也可以使用sed删除三行标题:

convert anim.png anim.pgm | sed '1,3d' > anim.bin

现在您已经拥有了一个仅包含纯像素的二进制文件,不包含日期/时间、作者和版权、调色板和压缩数据,您可以继续下一步操作。
第二步,一旦您将数据转换为合理的二进制格式,您需要将其转换为Intel Hex格式,为此您需要使用srec_cat,它可在Linux日常版本和Mac上通过homebrew获得。
然后,我没有测试过也从未使用过,我认为您会需要类似于以下内容的东西:
srec_cat anim.bin -binary -output -intel 

:020000040000FA
:20000000323535203235352032353520323535203235352032353520323535203235352000
:200020003235352032353520323535203235352032353520323535203235352032353520E0
:200040003235352032353520323535203235352032353520323535203235352032353520C0
:200060003235352032353520323535203235352032353520323535203235352032353520A0
:20008000323535203235352032353520323535203235352032353520323535203235352080
...
:207E8000353520323535203235352032353520323535203235352032353520323535203202
:207EA0003535203235352032353520323535203235352032353520323535203235352032E2
:147EC000353520323535203235352032353520323535200A2A
:00000001FF

摘要

你可以缩写和简化我上面提出的建议 - 我会将它留在那里,以便未来的人们能够理解它!

convert YourImage.png gray: | srec_cat - -binary -output -intel 

gray:是一个非常简单的ImageMagick格式,相当于没有头文件的PGM文件的二进制部分。与PGM一样,它每个像素使用一个字节,因此对于您的纯黑白需求来说效率会有些低。您可以通过查看文件大小来了解这一点- PGM文件为8192字节,因此每个像素为1字节。如果您真的非常想要每个像素1位,您可以使用PBM格式,如下所示:

convert YourImage.png pbm: | sed '1,3d' | srec_cat - -binary -output -intel 

注意:

  1. 从ImageMagick的v7版本开始,您应该将convert替换为magick,以避免与Windows内置的convert命令冲突,该命令将文件系统转换为NTFS。

  2. ImageMagick是一个相当大的软件包,您也可以使用NetPBM套件来完成同样的工作,并使用名为pngtopnm的工具来替换convert


非常感谢!我尝试将图像转换为二进制,然后使用srec_cat转换为十六进制...但我想我从未考虑过png中的垃圾。哇,我从未想过制作EPROM,这是过去的事情吧。看到有这样一个积极的社区来帮助,真的让我感动得热泪盈眶。 - Neko
我在使用Windows时遇到了“sed”命令的问题。有什么建议吗,亲爱的大师?它说“sed”不被可执行文件识别为内部或外部命令、程序或文件。 - Neko
Windows?呃!我从未尝试过,但根据这篇帖子,你可以使用 MORE +3 https://dev59.com/KGgu5IYBdhLWcg3wTFWi#11432438 - Mark Setchell
所以,我使用了more +3,并在bin上运行得很顺利。但是在此之后,当我使用命令srec_cat.exe 1.bin.new -binary -o 1.hex -intel时(其中1是我的镜像),它生成的十六进制文件比我需要的字节更多(我希望结尾为3FFH,如我所说,需要将图像限制为1kb,而且似乎有AHs和DHs而不是纯0在方块应该在的地方),而字节大小(intel hex格式的开头)为20H。非常抱歉一直麻烦你:( - Neko
使用 +3 命令之前,我需要先有一个文件。我该如何保存用 pbm 创建的二进制文件? - Neko
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接