Last active
January 29, 2025 15:46
-
-
Save Quasimondo/e47a5be0c2fa9a3ef80c433e3ee2aead to your computer and use it in GitHub Desktop.
Writing directly to the Raspberry PI framebuffer from Python (no GUI or X required)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# After a lot of searching and false or complicated leads I found this brilliant method | |
# that allows to use a numpy array to get direct read/write access to the rpi framebuffer | |
# https://stackoverflow.com/questions/58772943/how-to-show-an-image-direct-from-memory-on-rpi | |
# I thought it is worth sharing again since so it might someone else some research time | |
# | |
# The only caveat is that you will have to run this as root (sudo python yourscript.py), | |
# But you can get around this if you add the current user to the "video" group like this: | |
# usermod -a -G video [user] | |
# source: https://medium.com/@avik.das/writing-gui-applications-on-the-raspberry-pi-without-a-desktop-environment-8f8f840d9867 | |
# | |
# in order to clear the cursor you probably also have to add the user to the tty group | |
# usermod -a -G tty [user] | |
# Potentially also to the dialout group (not so sure about that, but I did it before I realized that a reboot is required) | |
# usermod -a -G dialout [user] | |
# IMPORTANT you will have to reboot once for this to take effect | |
import numpy as np | |
import os | |
# this turns off the cursor blink: | |
os.system ("TERM=linux setterm -foreground black -clear all >/dev/tty0") | |
# this is the frambuffer for analog video output - note that this is a 16 bit RGB | |
# other setups will likely have a different format and dimensions which you can check with | |
# fbset -fb /dev/fb0 | |
buf = np.memmap('/dev/fb0', dtype='uint16',mode='w+', shape=(576,720)) | |
# fill with white | |
buf[:] = 0xffff | |
for x in range(720): | |
# create random noise (16 bit RGB) | |
b = np.random.randint(0x10000,size=(576,720),dtype="uint16") | |
# make vertical line at x black | |
b[:,x]=0 | |
# push to screen | |
buf[:] = b | |
# turn on the cursor again: | |
os.system("TERM=linux setterm -foreground white -clear all >/dev/tty0") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment