Graphics files

August 23, 2026 · View on GitHub

Two layers: pygraphics loaders (eager, full image in RAM) and add-ons in pydevices-examples (TFT-specific helpers).

pygraphics package loaders

Built into pygraphics — see the graphics guide:

FunctionFormat
pygraphics.bmp_to_framebuffer(path)Windows BMP → FrameBuffer
pygraphics.pbm_to_framebuffer(path)PBM (1-bit)
pygraphics.pgm_to_framebuffer(path)PGM (grayscale)
pygraphics.load_image(path)Auto-detect PBM/PGM/BMP from header
pygraphics.save_image(fb, path)Write PBM/PGM/BMP for supported formats
pygraphics.FrameBuffer.from_file(path)Same as load_image
pygraphics.FrameBuffer.save(path)Same as save_image
pygraphics.FrameBuffer.export(path) / export_framebufferWrite importable .py module (BITMAP = bytearray(...))
pygraphics.FrameBuffer.from_bitmap(buf, w, h, fmt)Wrap buffer; zero-copy when buf is a writable bytearray
pygraphics.FrameBuffer.from_module(mod)Same using mod.WIDTH / HEIGHT / FORMAT / BITMAP

Memory notes

  • Files: PBM/PGM parsers allocate one pixel bytearray and fill it with readinto (peak ≈ one framebuffer). BMP already fills a single destination buffer row-by-row.
  • .py bitmaps: Prefer BITMAP = bytearray(...) so from_bitmap does not copy. Legacy memoryview(bytes) modules get one copy. This is separate from Font.export, which keeps a read-only memoryview for glyph indexing.

Save/load matrix

Framebuffer formatFileNotes
MONO_HLSBPBM (P4)1-bit portable bitmap
GS2_HMSBPGM (P5, max 3)2-bit grayscale
GS4_HMSBPGM (P5, max 15)4-bit grayscale
GS8PGM (P5, max 255)8-bit grayscale
RGB565BMP16-bit RGB565 Windows BMP

MONO_VLSB, MONO_HMSB, and other display-native formats are not saved directly — convert or blit to a supported buffer first.

Use these for icons and sprites that fit in RAM on MCU or desktop.

BMP565 (streaming)

pygraphics.BMP565 reads/writes Windows BMP files in RGB565 format (export from GIMP). Shared header/row logic also powers bmp_to_framebuffer and FrameBuffer.save() for RGB565.

Features:

  • Load entire file or stream slices for large images: BMP565[1:5, 6:10]
  • Row mirroring for rotated scroll backgrounds
  • Use an existing bytearray as buffer (screenshots)

Examples: bmp565_simpletest.py, bmp565_sprite.py, bmp565_scroll.py. Each one opens a .bmp from the filesystem, so they run on desktop and MCU but not in the browser.

To see FrameBuffer blitting live without an image file, run pbm_create_new.py, which builds an image in code and blits it, or framebuf_simpletest.py.

tft_text / tft_write bitmap helpers (pydevices-examples)

From @russhughes st7789py_mpy:

  • .bitmap() — decode .py image files from image_converter.py or sprites_converter.py; renders full image then blits
  • .pbitmap() — progressive line-at-a-time rendering with a one-line buffer

PNG

Experimental support in utils — probe with tools/png_test.py in the pdwidgets repo (CPython only; requires sibling pydevices-examples, pypng, and a local checkout of material-design-icons with its png/ tree, or PDWIDGETS_PNG_DIR).