Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/rm-hull/luma.oled/llms.txt

Use this file to discover all available pages before exploring further.

The canvas class is the primary way to draw text and graphics with luma.oled. It acts as a context manager that creates a Pillow ImageDraw object sized and configured for your device. When the with block exits, the finished image is automatically flushed to the display’s memory.

The canvas context manager

When you open a canvas context, luma.oled creates a PIL.ImageDraw object with the correct dimensions and bit depth for your device. All drawing happens on that in-memory image. As soon as the with block ends, the image is transferred to the display and the ImageDraw object is discarded.
from luma.core.interface.serial import i2c
from luma.core.render import canvas
from luma.oled.device import ssd1306

serial = i2c(port=1, address=0x3C)
device = ssd1306(serial)

with canvas(device) as draw:
    draw.rectangle(device.bounding_box, outline="white", fill="black")
    draw.text((30, 40), "Hello World", fill="white")

The bounding_box property

device.bounding_box returns a tuple (0, 0, width - 1, height - 1) that describes the full drawable area of the display. Passing it directly to draw.rectangle is a convenient way to fill or outline the entire screen without hardcoding pixel dimensions.

Available drawing methods

Because canvas exposes a standard PIL.ImageDraw object, every Pillow drawing primitive is available:
MethodDescription
draw.rectangle(xy, outline, fill)Draw a rectangle
draw.text(xy, text, fill, font)Render text
draw.line(xy, fill, width)Draw a line
draw.ellipse(xy, outline, fill)Draw an ellipse or circle
draw.polygon(xy, outline, fill)Draw a polygon
draw.point(xy, fill)Draw individual pixels

Reusing a canvas reference

Each with canvas(device) as draw: statement creates a fresh blank image — equivalent to clearing the screen first. If you want to redraw in a loop without re-creating the canvas object each iteration, keep a reference to it:
c = canvas(device)
for x in range(0, device.width, 10):
    with c as draw:
        draw.rectangle(device.bounding_box, outline="white", fill="black")
        draw.rectangle((x, 10, x + 8, 54), outline="white", fill="white")
The image is still flushed to the display at the end of each with block.
When a program ends, the display is automatically cleared. A short-lived script that exits immediately may never show a visible image — add a sleep() call at the end if needed.
For the full list of drawing methods, font loading, and image manipulation options, see the Pillow ImageDraw documentation.

Build docs developers (and LLMs) love