Home
OLED Bitmap Converter

Image, GIF or byte array to Arduino code for SSD1306, SH1106 & U8g2 OLED displays

Home / Guides / Display Image on SSD1306 Arduino
Hardware Tutorial

How to Display an Image on an SSD1306 OLED with Arduino

This comprehensive guide walks you through connecting a 0.96" or 0.91" I2C SSD1306 OLED to an Arduino, converting any PNG or JPG logo into a flash-friendly C byte array, and running tested code to draw it.

Step 1: Hardware Wiring (I2C)

The vast majority of 0.96-inch monochrome OLEDs communicate over I2C with four pins: GND, VCC, SCL, and SDA.

OLED Pin Arduino Uno / Nano ESP32 (Default) ESP8266 (NodeMCU)
GND GND GND GND
VCC 5V or 3.3V (check module) 3.3V 3.3V
SCL Pin A5 GPIO 22 D1 (GPIO 5)
SDA Pin A4 GPIO 21 D2 (GPIO 4)

Note: Most breakout boards include an on-board 3.3V voltage regulator and I2C pull-up resistors, making them safe for 5V Arduino Uno pins.

Step 2: Install Adafruit Libraries

In the Arduino IDE:

  1. Navigate to Sketch → Include Library → Manage Libraries...
  2. In the search filter, type Adafruit SSD1306 and click Install.
  3. When prompted to install dependencies (such as Adafruit GFX Library and Adafruit BusIO), click Install All.

Step 3: Convert Your Image with OLED Bitmap Converter

Arduino microcontrollers have strictly limited memory. Rather than loading an uncompressed image file from an SD card, you convert the graphic into a 1-bit monochrome array stored in flash program memory (PROGMEM).

  1. Open the OLED Bitmap Converter.
  2. Upload your PNG, JPG, or BMP file.
  3. Select 0.96" 128x64 SSD1306 and Arduino Uno.
  4. Adjust the brightness threshold slider to eliminate noise, and check Invert if your original is black on white.
  5. Copy the generated Arduino code.

Step 4: The Complete Working Arduino Sketch

Here is a tested sketch demonstrating how to define the bitmap in flash, initialize the display at address 0x3C, and render the graphic:

#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET    -1
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

// 64x64 pixel sample logo stored in PROGMEM (512 bytes)
const unsigned char logo_bmp[] PROGMEM = {
  0x00, 0x00, 0x00, 0x7e, 0x7e, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x03, 0xff, 0xff, 0xc0, 0x00, 0x00,
  0x00, 0x00, 0x0f, 0xff, 0xff, 0xf0, 0x00, 0x00,
  0x00, 0x00, 0x3f, 0x80, 0x01, 0xfc, 0x00, 0x00,
  0x00, 0x00, 0x7e, 0x00, 0x00, 0x7e, 0x00, 0x00,
  0x00, 0x00, 0xfc, 0x18, 0x18, 0x3f, 0x00, 0x00,
  // ... remaining rows generated by the converter ...
};

void setup() {
  Wire.begin();
  // Most 128x64 OLEDs use 0x3C; some variants use 0x3D
  if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
    // If initialization fails, loop indefinitely
    for (;;);
  }

  display.clearDisplay();
  
  // drawBitmap(x, y, bitmap_data, width, height, color)
  // Centering a 64x64 bitmap on a 128x64 display: x = (128 - 64)/2 = 32
  display.drawBitmap(32, 0, logo_bmp, 64, 64, SSD1306_WHITE);
  display.display();
}

void loop() {
  // Static image display
}

Step 5: Combining Graphics and Text

You can combine drawBitmap with text headers, sensor readouts, or borders on the same screen:

display.clearDisplay();

// Draw a 32x32 battery/sensor icon on the left
display.drawBitmap(0, 16, icon_bmp, 32, 32, SSD1306_WHITE);

// Draw title and value on the right
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
display.setCursor(42, 18);
display.print("SENSOR 1:");

display.setTextSize(2);
display.setCursor(42, 32);
display.print("24.5 C");

display.display();

Common Gotchas & Troubleshooting