Creating An Image Format For Embedded Hardware

Whether its one of those ubiquitous little OLED displays or a proper LCD panel, once you’ve got something a bit more capable than the classic 16×2 character LCD wired up to your microcontroller, there’s an excellent chance you’ll want to start displaying some proper images. Generally speaking that means you’ll be working with bitmap files, but as you might expect when pushing a decades-old file format into an application it was never intended for, things can get a little messy. Which is why [gfcwfzkm] has created the Portable Image File (PIF) format.

This low-overhead image format is designed specifically for microcontrollers, and can be decoded on devices with at least 60 bytes of free RAM. Images stored with PIF not only require fewer computational resources to process, but equally important, take up less space on flash. The format supports both color and monochrome images, and the GitHub repo even includes a graphical Python 3.10 tool that lets you convert your images to either .pif files or a .h header file for embedding directly into your C code.

[gfcwfzkm] has provided some source code to show you how to get the PIF library up and running, but as of the time of this writing, there isn’t any example code for using PIF within the Arduino environment. That’s no big deal for the old hands in the audience, but we’re interested in seeing how the community can make use of this file format once it’s available in a bit more beginner-friendly package. It’s one of the final unchecked items on the todo list though, so it shouldn’t be long now.

Of course nothing is wrong with using bitmaps to display images in your microcontroller projects, and there’s a certain advantage to fiddling around with the well-known image format. But if a new file type is all it takes to speed up access times and cram a few more images onto the chip, we’re definitely ready to upgrade.

61 thoughts on “Creating An Image Format For Embedded Hardware

  1. Great self-contained format here. One ‘.c’ and one ‘.h’ file to drop on your project and good to go.

    Introducing another format might not matter so much if it is just an internal thing with, say, ‘.png’ exposed to the user (for example a screenshot feature).

    Here is another format if lossless compression is desired:

  2. potential time saver. I´ve been fiddling enough with image converters, exporting to c headers, and this was time consuming.
    Now this should be natively supported by LVGL, and i can get rid of the lodepng lib !

  3. A few years ago I had a short look into storing images by microcontrollers for display on an TFT LCD, and one of the things I discovered was:

    Gimp / File / Export As / Select File Type / C source code

    This exporter also has some options for different formats and simple compression.

    1. You’re absolutely correct. Using Lena’s image is not and never was appropriate.

      The original impetus for using Lena was an act of casual sexism and objectification. By keeping this ‘tradition’ alive, we’re actively pushing away people who want to participate by making them uncomfortable. There are many other, more appropriate images that work just as well for this purpose.

      In fact, many high-impact journals now desk-reject articles that feature the original Lena image. If this objection is good enough for the editors of Nature nanotech, it ought to be good enough for us >:(

      1. Did you make any attempt at actually reading the documentation? BMP is specifically what he’s trying to improve on, and looking at the specs, he’s succeeded.

    1. to improve the wheel, you must first re-invent the wheel. you do the first part, loose interest and dont get to the second part. and that is why we have hundreds of image formats that are effectively the same.

      i did my own experiments, however i was doing experiments in texture compression. its interesting that all computer games use the same s3tc formats that were used with the voodoo line of 3d accelerators, and we still use them in all of our pc games, either directly or internally. on the arm side of the aisle, they have better formats with really interesting encoding schemes they either look better or are smaller than the s3tc formats in use, yet they have never made the jump to the pc side. the very research i was doing into texture compression revealed that i was in way over my head, and thats why i stopped.

  4. I found some similar online tools to convert images to 8bitRGB C code, and got them to display via esp32 composite in Ardurino IDE – was quite pleased it worked, although I had no specific use for it.

  5. 1. make transparent like in gif
    2. make different compression of part image for example face is important than sky
    3. meybe adding combining vector (svg) and pixel format

  6. Just a note about docs. “0x” is a C pre-processor thing and is not part of a base 16 number. I am not a C pre-processor if I can avoid it. Maybe just put HEX at the top of the column? It is a real pain to read a lot of hex with that darn decoration.

    ‘B/W’ could be ‘Mono’ instead. A monochrome image does not have to be black and white data.

    1. Thanks for the input! I will clarify and format the specification sheet a little regarding the hex values.
      Regarding the B/W & Mono, I’ve indeed used both of them to mean the same thing (a black and white only image). Another thing to fix in the documentation! (Monochrome, as you corrected me, is still possible via one of the Indexed-Colors modes)

    2. Re not being a C pre-processor, could you sort these in order least to greatest. I’ve not added any pre-processor notation so as to not confuse you.


Leave a Reply

Please be kind and respectful to help make the comments section excellent. (Comment Policy)

This site uses Akismet to reduce spam. Learn how your comment data is processed.