Repository navigation
Image Encoding
Images use a row-major stream of 4-bit palette indices, then Base64 encoding. Pixels are ordered left to right, top to bottom. There is no header or row padding.
Each byte stores the first pixel in its high nibble and the second in its low nibble:
byte = (first_pixel << 4) | second_pixel
For pixel (x, y), the stream index is y * width + x; the byte index is integer division by 2. Even stream indices use the high nibble. With odd image widths, a byte may contain the last pixel of one row and the first of the next.
pixel_count = width * height
raw_bytes = ceil(pixel_count / 2)
base64_characters = 4 * ceil(raw_bytes / 3)
If the total pixel count is odd, the last low nibble is unused. Pad it with zero; it is not rendered.
| Dimensions | Pixels | Raw bytes | Base64 characters |
|---|---|---|---|
| 2 × 2 | 4 | 2 | 4 |
| 3 × 1 | 3 | 2 | 4 |
| 100 × 100 | 10,000 | 5,000 | 6,668 |
| 792 × 272 | 215,424 | 107,712 | 143,616 |
A full-display packed image exceeds the firmware's 128 KiB response-body limit once Base64 encoded, even before JSON overhead. Splitting it into commands inside one response does not reduce that total. Prefer drawing commands and smaller image regions.
Use 0 black, 1 white, 2 yellow, 3 red, and 4 transparent. The default skip index is 4; the command can override it with transparent. The display does not support fractional alpha.
For a 2 × 2 image containing black, white, yellow, transparent, the bytes are 01 24, encoded as ASQ=. A 3 × 1 image containing black, white, red can use bytes 01 30, encoded as ATA=.
See Draw Image and Color Palette.