使用Python绘制不同的Linux帧缓冲区?

问题描述 投票:0回答:2

我想用 python 绘制非标准的 Linux 帧缓冲区。我有一个运行 Ubuntu 的 Odroid C4 SBC,带有 3.2 英寸 LCD 屏幕。 LCD 为 320x240 16 位颜色。我的大部分交互都是通过 HDMI 连接的显示器进行的。屏幕使用 /dev/fb4 作为帧缓冲区,我的显示器位于 /dev/fb0。我可以以不同的方式直接写入 /dev/fb4,并且内容会显示在屏幕上。我想使用 python 在小屏幕上绘制简单的文本和图像,但我不确定要使用哪些模块以及如何将它们指向 /dev/fb4。

我找到了各种可以让您绘制到主帧缓冲区的模块,例如 pygame,但我无法找到有关如何将它们指向不同帧缓冲区的说明。

python framebuffer odroid
2个回答
2
投票

这里有一些代码片段可以帮助您创建自己的代码。

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

注意:写入帧缓冲区是一项受限制的操作。您必须将您的用户名添加到“视频”组。
如果您需要更多信息,请详细说明您的问题。
玩得开心!


0
投票

我想我必须给你一个更清晰的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()

© www.soinside.com 2019 - 2024. All rights reserved.