Skip to content

Images Guide

Microesque edited this page Dec 14, 2024 · 2 revisions

When working with a display, you'll naturally want to be able to display images on it. Given that SSD1306 displays can only turn their pixels on or off in a single color, they can only display binary images.

Images can be displayed with the ssd1306_draw_bitmap() function. This function uses the XBM format, which is a file format used to store binary images.

.xbm files store images as plain text C arrays. Meaning, you can simply convert your images to .xbm format and directly copy their contents into your code to display the images.

To convert your images to .xbm, you can use free tools like GIMP or an online converter (search for "Image to XBM converter"). Below is an example walkthrough of the process.

Note: Most XBM converters use a brightness threshold of 50% when converting images to binary. This doesn't always result in the best-looking image. There are websites that allow you to set the threshold manually, such as https://javl.github.io/image2cpp/. Remember to tick Invert image colors and Swap bits in byte, and choose the Horizontal - 1 bit per pixel option to match the XBM format.


Imagine that you are trying to display the image below with the resolution 128x64:

img

If you convert this image to an .xbm file and open it in a text editor, the contents will look something like:

#define 625784489091_width 128
#define 625784489091_height 64
static char 625784489091_bits[] = {
  0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0x3F, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 
  ...
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 
  0x00, 0x00, 0x00, 0x00, };

After a few adjustments, you can simply copy the contents of this file into your project and display the image:

  • Most embedded systems compilers store const variables in flash memory, so add the const qualifier to the bitmap.
  • The ssd1306_draw_bitmap() function requires a uint8_t array, so change the array type to uint8_t.
  • Give the bitmap a proper name.

At the end, the code looks like:

#define GigaChad_width 128
#define GigaChad_height 64
static const uint8_t GigaChad_bits[] = {
  0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0x3F, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 
  ...
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 
  0x00, 0x00, 0x00, 0x00, };

Now, you can display the image with the ssd1306_draw_bitmap() function:

The arguments are:

  • Arg1: The address of your ssd1306_display structure.
  • Arg2: x-coordinate of the top left of your image.
  • Arg3: y-coordinate of the top left of your image.
  • Arg4: Address of the image bitmap.
  • Arg5: Width of the image in pixels.
  • Arg6: Height of the image in pixels.
  • Arg7: true to overwrite the contents in the background; false to draw transparent.
ssd1306_draw_bitmap(&display,
                    0,
                    0,
                    GigaChad_bits,
                    GigaChad_width,
                    GigaChad_height,
                    true);

The final source code to display the image at the beginning is:

/* Image definitions */
#define GigaChad_width 128
#define GigaChad_height 64
static const uint8_t GigaChad_bits[] = {
  0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0x3F, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 
  ...
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 
  0x00, 0x00, 0x00, 0x00, };

/* Draw the image */
ssd1306_draw_bitmap(&display,
                    0,
                    0,
                    GigaChad_bits,
                    GigaChad_width,
                    GigaChad_height,
                    true);
ssd1306_display_update(&display);
img