Linux framebuffer 编程入门:直接操作显存画图
在 Linux 下,我们可以通过 framebuffer(帧缓冲) 技术直接在屏幕上画图,而不需要复杂的 GUI 库。
1. 什么是 framebuffer?
framebuffer 是 Linux 内核为图形显示提供的一套接口,允许用户空间程序直接访问显存数据。
通过 /dev/fb0
这个设备文件,我们可以获取屏幕参数、映射显存,然后直接修改像素。
2. 基本流程
操作 framebuffer 的基本步骤如下:
打开显示设备
int fd = open("/dev/fb0", O_RDWR);
获取显示设备参数
分辨率(
xres
、yres
)虚拟分辨率(
xres_virtual
、yres_virtual
)像素格式(RGB888、RGB565等)
ioctl(fd, FBIOGET_VSCREENINFO, &vinfo);
建立显存映射
unsigned int *pmem = mmap(NULL, screensize, PROT_READ | PROT_WRITE,MAP_SHARED, fd, 0 );
写入像素值
例如在
(x, y)
位置画一个像素:*(pmem + y * vinfo.xres_virtual + x) = 0x00FF0000; // 红色
解除映射
munmap(pmem, screensize);
关闭设备
close(fd);
3. 显存与坐标的关系
假设屏幕分辨率是 800 × 600
,像素格式是 RGB888(4 字节对齐):
(x, y)
像素在显存中的偏移:
偏移 = y * xres_virtual + x
例如 (400, 300)
的像素地址:
pmem + 800 * 300 + 400
对应像素值示例:
0x00FF0000 → 红色
0x0000FF00 → 绿色
0x000000FF → 蓝色
4. mmap 参数解析
void *mmap(void *addr, size_t length, int prot, int flags,int fd, off_t offset);
addr:用户空间起始地址
一般传 NULL
让系统自动分配
length:映射的长度(字节数)
prot:映射区域权限
PROT_READ
允许读
PROT_WRITE
允许写
flags:常用 MAP_SHARED
(修改会同步到显存)
fd:open("/dev/fb0", O_RDWR)
得到的文件描述符
offset:映射偏移量(一般 0 表示从显存开头)
返回值:
成功 → 映射的用户空间首地址
失败 → MAP_FAILED
5. 像素格式
RGB888:每像素 3 字节(但一般对齐到 4 字节)
RGB565:每像素 2 字节常见 24 位
RGB888 存储顺序:
RGB(红绿蓝)
BGR(蓝绿红)例如纯白色:
R: 0xFF
G: 0xFF
B: 0xFF
6. 示例:画两个点
// 红色
unsigned int red = 0x00FF0000;// 在 (100, 100) 画一个像素
*(pmem + 100 * vinfo.xres_virtual + 100) = red;// 在 (400, 300) 画一个像素
*(pmem + 300 * vinfo.xres_virtual + 400) = red;
总结
framebuffer 编程直接操作显存,适合做嵌入式 UI、简单绘图、屏幕测试等场景。掌握了分辨率、像素格式和显存映射后,就可以自由地绘制任意图形了。