User Rating 0.0 โ˜…โ˜…โ˜…โ˜…โ˜…
Total Usage 0 times
Drop image here or click to upload PNG, BMP, JPG, GIF • Max 1024×1024
Is this tool helpful?

Your feedback helps us improve.

โ˜… โ˜… โ˜… โ˜… โ˜…

About

Embedded display controllers like SSD1306, ST7735, and ILI9341 consume image data as packed byte arrays stored in program memory. A single misaligned bit order or wrong scan direction produces garbled output on screen. This tool decodes any raster image, applies configurable luminance thresholding (T โˆˆ [0, 255]) using the BT.601 standard (L = 0.299R + 0.587G + 0.114B), and packs the resulting 1-bit pixels into bytes with precise control over bit order and scan direction. Optional Floyd-Steinberg dithering preserves perceptual detail that hard thresholding destroys.

The converter targets real hardware constraints. Arduino PROGMEM arrays must use const qualifiers and correct data types to avoid RAM exhaustion on ATmega328P chips with only 2 KB SRAM. Output format errors cause silent failures: the display shows noise, not an error message. This tool validates dimensions, calculates exact byte counts (W ร— H รท 8), and generates copy-ready code. Note: images exceeding 128ร—64 pixels may exceed flash capacity on 8-bit microcontrollers.

bitmap to byte array image to c array arduino bitmap oled display image embedded graphics monochrome converter progmem array ssd1306 image

Formulas

Each pixel is first converted to luminance using the ITU-R BT.601 luma coefficients:

L = 0.299 โ‹… R + 0.587 โ‹… G + 0.114 โ‹… B

The luminance value is compared against a user-defined threshold T to produce a binary pixel P:

P = {
1 if L < T (dark pixel, ink on)0 if L โ‰ฅ T (light pixel, background)

When Floyd-Steinberg dithering is enabled, the quantization error e is distributed to neighboring pixels:

e = L โˆ’ Q
pixel(x+1, y) += e โ‹… 716
pixel(xโˆ’1, y+1) += e โ‹… 316
pixel(x, y+1) += e โ‹… 516
pixel(x+1, y+1) += e โ‹… 116

Binary pixels are packed into bytes. For horizontal MSB-first packing, byte index B and bit position b for pixel at column x, row y in an image of width W:

B = y โ‹… ceil(W8) + floor(x8)
b = 7 โˆ’ (x mod 8)

Total byte count for a 1-bit monochrome image:

N = ceil(W8) โ‹… H

Where R, G, B are red, green, blue channel values (0 - 255); L is luminance; T is threshold; Q is quantized output (0 or 255); W is image width in pixels; H is image height in pixels; N is total bytes in the output array.

Reference Data

Display ControllerResolutionColor DepthInterfaceByte OrderScan DirectionTypical MCUFlash Usage
SSD1306128ร—641-bit monoIยฒC / SPILSB first (vertical)Vertical (page mode)ATmega328P1024 bytes
SSD1309128ร—641-bit monoIยฒC / SPILSB firstVerticalESP321024 bytes
SH1106132ร—641-bit monoIยฒC / SPILSB firstVerticalATmega328P1056 bytes
ST7565128ร—641-bit monoSPIMSB firstHorizontalATmega25601024 bytes
Nokia 5110 (PCD8544)84ร—481-bit monoSPIMSB firstHorizontalATmega328P504 bytes
ST7735128ร—16016-bit RGB565SPIMSB firstHorizontalESP3240960 bytes
ILI9341240ร—32016-bit RGB565SPIMSB firstHorizontalESP32153600 bytes
MAX72198ร—8 (chainable)1-bit monoSPIMSB firstHorizontalATmega328P8 bytes
HT16K3316ร—81-bit monoIยฒCLSB firstHorizontalATmega328P16 bytes
EPD (e-Paper) 2.9โ€ณ296ร—1281-bit monoSPIMSB firstHorizontalESP324736 bytes
EPD (e-Paper) 4.2โ€ณ400ร—3001-bit monoSPIMSB firstHorizontalESP3215000 bytes
UC1701128ร—641-bit monoSPIMSB firstVerticalSTM321024 bytes
SSD1351128ร—12816-bit RGB565SPIMSB firstHorizontalESP3232768 bytes

Frequently Asked Questions

MSB-first (Most Significant Bit first) packs the leftmost pixel into bit 7 of each byte. LSB-first packs the leftmost pixel into bit 0. The SSD1306 in vertical page mode expects LSB-first (bit 0 is top pixel of the 8-pixel column). The PCD8544 (Nokia 5110) and most e-Paper displays expect MSB-first with horizontal scanning. Using the wrong bit order produces a horizontally mirrored or completely garbled image.
Vertical scanning packs 8 vertically stacked pixels into one byte. This matches the SSD1306 page-addressing mode where each byte controls an 8-pixel-tall column. The image height must be a multiple of 8 for clean packing. If your display uses page-mode addressing (SSD1306, SSD1309, SH1106, UC1701), select vertical scan. If it uses line-mode addressing (ST7735, ILI9341, PCD8544, e-Paper), select horizontal scan.
OLED displays are emissive: a bit value of 1 turns a pixel ON (bright), and 0 is OFF (dark). If your source image has a white background, the threshold logic sets background pixels to 0 (correct for OLED). However, some libraries interpret 1 as black (ink-on-paper convention). Use the Invert toggle to flip all bits. This is equivalent to applying a bitwise NOT (ยฌ) to every byte in the array.
Hard thresholding discards all grayscale information: any pixel above T becomes white, below becomes black. Floyd-Steinberg dithering distributes the quantization error to neighboring pixels using fixed coefficients (716, 316, 516, 116). This creates dot patterns that simulate grayscale when viewed at display resolution. It is particularly effective for photographs on 128ร—64 OLEDs where hard thresholding loses all detail.
The ATmega328P has 32 KB flash memory, of which roughly 0.5 - 2 KB is used by the bootloader. Your compiled sketch typically uses 4 - 12 KB. That leaves approximately 18 - 27 KB for image data. A 128ร—64 monochrome bitmap uses 1024 bytes. You can store roughly 18 - 26 full-screen frames. For larger displays like 240ร—320 at 16-bit color (153,600 bytes), you need ESP32 or external flash.
No. The byte array size is determined solely by image dimensions: ceil(W รท 8) ร— H bytes for horizontal scan. The threshold only changes which bits are 1 vs 0 within those bytes. A lower threshold produces fewer dark pixels (sparser image). A higher threshold produces more dark pixels (denser image). The total byte count remains constant regardless of threshold setting.