So I am developing a type of tamagotchi (virtual pet) for my microprocessors final. I made my own images 128x64 pixels long, as I am using a display with that resolution, so each image weighs 1Kbytes. I am using an at89s52 (8052) microcontroller and it doesn't have enough memory to store all the animations I want. My plan (and I kind of want to keep it that way) is to use an EPROM to save all my images with intel hex format (the programmer I am using is SUPERPRO and it imports that type of files). Of course the assembly code will be easy for me after the point where I have the data in the ROM. I am not that good of a programmer to develop a code that does exaclty what I want (convert images to intel hex), and all the software I have tried doesn't generate them correctly (inserts hex values that aren't supposed to be there, for example: in a blank space there is supposed to be only zeroes, and there is another value). I have tried with png with transparent background, with white background and jpg. The images I have are such:
https://i.sstatic.net/86yCD.jpg (it seems I am not allowed to post images here)
I don´t see much help in other places of the internet, so the answer to this question would be of great help for future MCU-based programmers. Thank you.
It's about 30 years since I last made an EPROM :-)
Anyway, you need 2 things...
Part One
Firstly, your files are PNG format which means they have dates, times, palettes, gamma chunks and a bunch of zlib
compressed data and you can't just copy that to a screen buffer. So, you need to convert the PNGs to a simple binary format where 0 is off and 1 is on and there is nothing else in the file. The easiest way to do that is with ImageMagick which is installed on most Linux platforms and is available for free on macOS and Windows. Let's say one of your frames is called anim.png
and we want to get it to a simple format, like PGM
(Portable GreyMap - see Wikipedia description) we can use ImageMagick like this at the console:
convert anim.png -compress none anim.pgm
The first few lines will be:
P2
128 64
255
255 255 255 255 255 255 255 ...
...
...
because the image is 128x64 and the maximum brightness in the file is 255. Then all the data follows in ASCII (because I put -compress none
). In there, 255 represents white and 0 represents black.
As that is too big for the screen, here is an image of how it looks - hopefully you can see your black box as a bunch of zeroes in the middle at the bottom:
Now, if you run that same command again, but remove the -compress none
, the same header will be produced but the data will follow in binary.
convert anim.png anim.pgm
And we can also use sed
to delete the 3 lines of header:
convert anim.png anim.pgm | sed '1,3d' > anim.bin
Now you have a binary file of just pure pixels that is free of dates/times, author and copyrights, palettes and compressed data, you can pass to the next part.
Part 2
Secondly, once you have got your data in a sensible binary format you need to convert it to Intel Hex, and for that you need srec_cat
which is available for Linux daily and via homebrew on a Mac.
Then, I haven't tested this and have never used it, I think you will want something like:
srec_cat anim.bin -binary -output -intel
:020000040000FA
:20000000323535203235352032353520323535203235352032353520323535203235352000
:200020003235352032353520323535203235352032353520323535203235352032353520E0
:200040003235352032353520323535203235352032353520323535203235352032353520C0
:200060003235352032353520323535203235352032353520323535203235352032353520A0
:20008000323535203235352032353520323535203235352032353520323535203235352080
...
:207E8000353520323535203235352032353520323535203235352032353520323535203202
:207EA0003535203235352032353520323535203235352032353520323535203235352032E2
:147EC000353520323535203235352032353520323535200A2A
:00000001FF
Summary
You can abbreviate and simplify what I am suggesting above - I will leave it there so folks can understand it in future though!
convert YourImage.png gray: | srec_cat - -binary -output -intel
The gray:
is a very simple ImageMagick format equivalent to just the binary part of a PGM file without any header. Like PGM
it uses one byte per pixel so it will be somewhat inefficient for your pure black and white needs. You can see that by looking at the file size - the PGM file is 8192 bytes, so 1 byte per pixel. If you really, really want 1 bit per pixel, you could use PBM
format like this:
convert YourImage.png pbm: | sed '1,3d' | srec_cat - -binary -output -intel
Note:
From v7 of ImageMagick onwards, you should replace convert
by magick
so as to avoid clashing with Windows' built-in convert
command that converts filesystems to NTFS.
ImageMagick is quite a large package, you could do this equally well just with the NetPBM suite, and use the tool called pngtopnm
in place of convert
.