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

huangapple go评论52阅读模式
英文:

Draw to different linux framebuffers with Python?

问题

我想使用Python在非标准的Linux帧缓冲区上绘制内容。我使用的是Odroid C4单板计算机运行Ubuntu,配有3.2英寸LCD屏幕帽。LCD屏幕分辨率为320x240,16位色深。我主要通过HDMI连接的显示器进行交互。LCD屏幕使用/dev/fb4作为帧缓冲区,而我的显示器位于/dev/fb0上。我可以直接以不同的方式向/dev/fb4写入内容,然后内容会显示在屏幕上。我想使用Python在小屏幕上绘制简单的文本和图像,但我不确定应该使用哪些模块以及如何将它们指向/dev/fb4。

我找到了一些允许您在主帧缓冲区上绘制内容的模块,比如pygame,但我还没有找到如何将它们指向不同帧缓冲区的说明。

英文:

I would like to draw on a non-standard linux frame buffer with python. I have a Odroid C4 SBC running Ubuntu, with a 3.2 inch LCD screen hat. The LCD is 320x240 16-bit color. I do most of my interaction with a monitor connected through hdmi. The screen uses /dev/fb4 as it's framebuffer, and my monitor is on /dev/fb0. I can directly write to /dev/fb4 in different ways and and stuff shows up on the screen. I'd like to use python to draw simple text and images on the small screen but I'm not sure what modules to use and how to point them at /dev/fb4.

I have found various modules that let you draw to the main framebuffer, like pygame, but I haven't been able to find instructions on how to point them at a different framebuffer.

答案1

得分: 2

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

# 导入模块
import mmap  # 共享内存
import sys   # 退出

# 设备由设备驱动程序创建
fbN = 'fb4'

# 获取宽度和高度
f = open(f"/sys/class/graphics/{fbN}/virtual_size", "r")
wh = f.read()
wa, ha = wh.split(',')
w = int(wa)  # 宽度
h = int(ha)  # 高度
f.close

# 获取每像素位数
f = open(f"/sys/class/graphics/{fbN}/bits_per_pixel", "r")
self.bpp = int(f.read())
if not self.bpp in (16,32):
  print("不支持的每像素位数")
  sys.exit()
f.close()

# 打开帧缓冲并将其映射到Python字节数组
fbdev = open(f"/dev/{fbN}", mode='r+b')  # 以读写模式打开
fb = mmap.mmap(fbdev.fileno(), w * h * bpp//8, mmap.MAP_SHARED, mmap.PROT_WRITE|mmap.PROT_READ)

# 示例:在位置x,y处写入像素
x, y = 5, 13
if bpp == 32:
  r, g, b, a = 40, 80, 120, 80  # 任意颜色
  p = bytearray.fromhex('%02x %02x %02x %02x' % (b, g, r, a))
else:
  r, g, b, a = 10, 20, 30, 1  # 任意颜色
  m = r << 12 + g << 5 + b  # 打包颜色
  p = bytearray.fromhex('%02x %02x' % (m >> 8, m & 0xFF))
pos = ((y * w + x) * len(p))
fb[pos:pos+len(p)] = p[:]  # 绘制像素

编程自己的文本到像素例程非常简单,只要使用等宽位图字体(查看/usr/share/consolefonts/)。psf文件格式在https://en.wikipedia.org/wiki/PC_Screen_Font中有文档。

注意:写入帧缓冲是受限制的操作。您必须将用户名添加到'video'组中。如果需要更多信息,请详细描述您的问题。祝玩得开心!

英文:

Here are some code snippets to help you create your own code.

import mmap # shared memory
import sys  # exit

fbN = &#39;fb4&#39;   # device created by the device driver

# get width and height
f = open( f&quot;/sys/class/graphics/{fbN}/virtual_size&quot;, &quot;r&quot;)
wh = f.read()
wa,ha = xy.split( &#39;,&#39;)
w = int( wa) # width
h = int( ha) # height
f.close

# get bits per pixel
f = open( f&quot;/sys/class/graphics/{fbN}/bits_per_pixel&quot;, &quot;r&quot;)
self.bpp = int( f.read())
if not self.bpp in (16,32):
  print( &quot;Unsupported bpp&quot;)
  sys.exit()
f.close()

# open framebuffer and map it onto a python bytearray
  fbdev = open( f&quot;/dev/{fbN}&quot;, mode=&#39;r+b&#39;) # 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( &#39;%02x %02x %02x %02x&#39; % ( b,g,r,a))
else:
  r,g,b,a = 10,20,30,1 # arbitrary color
  m = r&lt;&lt;12 + g&lt;&lt;5 + b # pack colors
  p = bytearray.fromhex( &#39;%02x %02x&#39; % ( m&gt;&gt;8, m&amp;0xFF))
pos = (( y * w  + x) * len(p))
fb[pos:pos+len(p)] = p[:] # draw pixel

It's pretty easy to program your own text-to-pixel routine if you use a monospaced bitmapped font (look into /usr/share/consolefonts/). psf file format is documented in https://en.wikipedia.org/wiki/PC_Screen_Font

Note: writing to a framebuffer is a restricted operation. You must add your username to 'video' group.
If you need more info, please detail your question.
Have fun!

huangapple
  • 本文由 发表于 2023年5月29日 22:19:57
  • 转载请务必保留本文链接:https://go.coder-hub.com/76358117.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定