我想用 python 绘制非标准的 Linux 帧缓冲区。我有一个运行 Ubuntu 的 Odroid C4 SBC,带有 3.2 英寸 LCD 屏幕。 LCD 为 320x240 16 位颜色。我的大部分交互都是通过 HDMI 连接的显示器进行的。屏幕使用 /dev/fb4 作为帧缓冲区,我的显示器位于 /dev/fb0。我可以以不同的方式直接写入 /dev/fb4,并且内容会显示在屏幕上。我想使用 python 在小屏幕上绘制简单的文本和图像,但我不确定要使用哪些模块以及如何将它们指向 /dev/fb4。
我找到了各种可以让您绘制到主帧缓冲区的模块,例如 pygame,但我无法找到有关如何将它们指向不同帧缓冲区的说明。
这里有一些代码片段可以帮助您创建自己的代码。
import mmap # shared memory
import sys # exit
fbN = 'fb4' # device created by the device driver
# get width and height
f = open( f"/sys/class/graphics/{fbN}/virtual_size", "r")
wh = f.read()
wa,ha = xy.split( ',')
w = int( wa) # width
h = int( ha) # height
f.close
# get bits per pixel
f = open( f"/sys/class/graphics/{fbN}/bits_per_pixel", "r")
self.bpp = int( f.read())
if not self.bpp in (16,32):
print( "Unsupported bpp")
sys.exit()
f.close()
# open framebuffer and map it onto a python bytearray
fbdev = open( f"/dev/{fbN}", mode='r+b') # open R/W
fb = mmap.mmap( fbdev.fileno(), w * h * bpp//8, mmap.MAP_SHARED, mmap.PROT_WRITE|mmap.PROT_READ)
# example: write a pixel at position x,y
# the following code support 2 bpp: 32 bits (RGBA) and 16 bits (packed RGB)
x,y = 5,13
if bpp == 32:
r,g,b,a = 40,80,120,80 # arbitrary color
p = bytearray.fromhex( '%02x %02x %02x %02x' % ( b,g,r,a))
else:
r,g,b,a = 10,20,30,1 # arbitrary color
m = r<<12 + g<<5 + b # pack colors
p = bytearray.fromhex( '%02x %02x' % ( m>>8, m&0xFF))
pos = (( y * w + x) * len(p))
fb[pos:pos+len(p)] = p[:] # draw pixel
如果您使用等宽位图字体,那么编写您自己的文本到像素例程非常容易(查看 /usr/share/consolefonts/)。 psf 文件格式记录在 https://en.wikipedia.org/wiki/PC_Screen_Font
注意:写入帧缓冲区是一项受限制的操作。您必须将您的用户名添加到“视频”组。
如果您需要更多信息,请详细说明您的问题。
玩得开心!
我想我必须给你一个更清晰的Python代码:
import os
import sys # for exit
import mmap # shared memory
frame_buffer_number = 'fb0' # device created by the device driver
# get width and height
f = open(f"/sys/class/graphics/{frame_buffer_number}/virtual_size", "r")
width_and_height = f.read()
width_string, height_string = width_and_height.split(',')
width = int(width_string) # width
height = int(height_string) # height
f.close
# get bits per pixel
f = open(f"/sys/class/graphics/{frame_buffer_number}/bits_per_pixel", "r")
bpp = int(f.read())
if not bpp in (16, 32):
print("Unsupported bpp")
sys.exit()
f.close()
# open framebuffer and map it onto a python bytearray
frame_buffer_device = open(f"/dev/{frame_buffer_number}", mode='r+b') # open R/W
frame_buffer_memory_map = mmap.mmap(frame_buffer_device.fileno(), width * height * bpp//8, mmap.MAP_SHARED, mmap.PROT_WRITE | mmap.PROT_READ)
color = 255
frame_buffer_memory_map.write(color.to_bytes(1, byteorder='little') * width * height * 3)
"""
# Copy the image pixel data to the framebuffer
for y in range(height):
for x in range(width):
r, g, b = 255, 255, 255
# Calculate the offset in framebuffer memory
offset = (y * width + x) * 3
# Write the pixel data to the framebuffer mmap
frame_buffer_memory_map[offset + 0] = r
frame_buffer_memory_map[offset + 1] = g
frame_buffer_memory_map[offset + 2] = b
"""
# Close the framebuffer device and mmap
frame_buffer_memory_map.close()
frame_buffer_device.close()