Optimising RAW Images For An E-ink Display

Whilst building the e-ink weather display for the Pico I’ve had to make a number of RAW images. I’ve been doing this by opening PNGs in Photoshop, converting them to grayscale, changing them to Bitmap (or 1-bit images) and then, because Photoshop won’t let me save a 1-bit image as RAW, I convert them back to grayscale and save as RAW.

For the 65×65 image for the daily weather summary this comes out to 4,224 bytes. Not a lot in the modern world, but when the Pico has such small storage space, and as I was planning to do day and night versions of each thumbnail, I needed two copies of fifteen different icons, making 123kb in total.

It was a waste of space as the e-ink display only displays 1-bit data, and therefore every image was taking eight times more storage space than necessary.

There are scripts available for creating 1-bit RAW images from PNGs, but I decided to experiment with another very clever thing that somebody else (Lucky Resistor) had written: the Micropython Bitmap Tool.

Essentially, it takes an image and turns it into a Python (or Micropython) byte string, so the image of the sun (first one above) becomes this:

bytearray(
        b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
        b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
        b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x80\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7c'
        b'\xfe\xff\xfe\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x80\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
        b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x0f\x1f\x1f\x3e\x1c\x08\x00\x80\x80\xc0\xe0\xe0\xe0'
        b'\xf0\xf1\xf1\xf1\xf0\xe0\xe0\xe0\xc0\x80\x80\x00\x08\x1c\x3e\x1f\x0f\x0f\x07\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
        b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\xc0\xc0\xc0\xc0\xc0\xc0\xc0\x80\x00\x00\x00\xf0\xfc\xfe\xff\x1f\x07\x03\x01'
        b'\x01\x01\x00\x00\x00\x00\x01\x01\x03\x07\x1f\xff\xfe\xfc\xe0\x00\x00\x00\x80\xc0\xc0\xc0\xc0\xc0\xc0\xc0\x80\x00\x00\x00\x00\x00'
        b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x03\x03\x03\x03\x03\x01\x00\x00\x00\x00\x07\x1f\x7f\xff\xf8\xf0\xe0'
        b'\xc0\x80\x80\x80\x80\x80\x80\x80\xc0\xe0\xf0\xfc\xff\x7f\x1f\x07\x00\x00\x00\x00\x01\x03\x03\x03\x03\x01\x01\x00\x00\x00\x00\x00'
        b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x40\xe0\xf0\xf8\xfc\x7c\x3c\x08\x00\x00\x01\x01'
        b'\x03\x03\x07\x07\x87\x87\x87\x07\x07\x03\x03\x01\x01\x00\x00\x08\x3c\x7c\xfc\xf8\xf0\xe0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
        b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00'
        b'\x00\x00\x00\x00\x1f\x7f\x7f\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
        b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
        b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
        b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
        b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
        b'\x00\x00\x00\x00\x00\x00\x00\x00\x00')

The advantage of this is that it takes a lot less space.

The disadvantage, as I found, is that loading images and exporting them and pasting into an array to do image lookups was really boring. And in the end, once I’d written a bit of code to look up which bytearray to use, instead of which image file to load, I had a 77kb file i.e. I’d only saved about 40% versus the grayscale versions.

The lesson, I guess, is that maybe next time I should learn how to make 1-bit RAW images with something like ImageMagick. The saving was so negligible for the effort it took that for the tiny images on the display I just stuck with my 8-bit RAW files – all 46.8kb of them.

Leave a Reply

Your email address will not be published. Required fields are marked *