当前位置: 首页 > news >正文

Linux framebuffer 编程入门:直接操作显存画图

在 Linux 下,我们可以通过 framebuffer(帧缓冲) 技术直接在屏幕上画图,而不需要复杂的 GUI 库。

1. 什么是 framebuffer?

framebuffer 是 Linux 内核为图形显示提供的一套接口,允许用户空间程序直接访问显存数据。
通过 /dev/fb0 这个设备文件,我们可以获取屏幕参数、映射显存,然后直接修改像素。

2. 基本流程

操作 framebuffer 的基本步骤如下:

  1. 打开显示设备

    int fd = open("/dev/fb0", O_RDWR);
    
  2. 获取显示设备参数

    • 分辨率(xresyres

    • 虚拟分辨率(xres_virtualyres_virtual

    • 像素格式(RGB888、RGB565等)

    ioctl(fd, FBIOGET_VSCREENINFO, &vinfo);
    
  3. 建立显存映射

    unsigned int *pmem = mmap(NULL, screensize, PROT_READ | PROT_WRITE,MAP_SHARED, fd, 0
    );
    
  4. 写入像素值

    • 例如在 (x, y) 位置画一个像素:

      *(pmem + y * vinfo.xres_virtual + x) = 0x00FF0000; // 红色
      
  5. 解除映射

    munmap(pmem, screensize);
    
  6. 关闭设备

    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(修改会同步到显存)

fdopen("/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、简单绘图、屏幕测试等场景。掌握了分辨率、像素格式和显存映射后,就可以自由地绘制任意图形了。

http://www.dtcms.com/a/330327.html

相关文章:

  • Flutter权限管理三步曲:检查、申请、处理全攻略
  • 【超算】算力的精度,数据中心的划分标准与行业现状(国家超级计算机,企业万卡GPU集群)
  • 深入详解C语言的循环结构:while循环、do-while循环、for循环,结合实例,讲透C语言的循环结构
  • 关于linux软件编程4:目录IO和一些时间函数
  • PAT 1065 A+B and C (64bit)
  • 驱动开发系列62 - glBufferDataARB实现分析
  • Windows下cuda的安装和配置
  • BGP 笔记梳理
  • 110. 字符串接龙
  • 【Spring AI 1.0.0】Spring AI 1.0.0框架快速入门(6)——MCP Client(MCP客户端)
  • 最新Coze(扣子)智能体工作流:用Coze实现「图片生成-视频制作」全自动化,3分钟批量产出爆款内容
  • Docker网络命名空间隔离与VPS服务器环境的连通性测试方法解析
  • kali linux 2025.2配置局域网打印服务器惠普打印机HP1108p
  • MySQL查询表结构、表大小
  • 告别意外中断,iOS辅助工具按键精灵「异常停止重启脚本」功能介绍
  • <c1:C1DateTimePicker的日期时间控件,控制日期可以修改,时间不能修改,另外控制开始时间的最大值比结束时间小一天
  • git clone 支持在命令行临时设置proxy
  • 康托展开与逆康托展开
  • 词向量转化
  • RocketMQ 消息存储机制 CommitLog和ConsumerQu
  • 第八课:python的运算符
  • 从 VLA 到 VLM:低延迟RTSP|RTMP视频链路在多模态AI中的核心角色与工程实现
  • 论文分享 | Flashboom:一种声东击西攻击手段以致盲基于大语言模型的代码审计
  • 04-spring-手写spring-demo-aop0V1
  • Canal解析MySQL Binlog原理与应用
  • Unity、C#常用的时间处理类
  • Laravel 使用ssh链接远程数据库
  • 使用 Simple Floating Menu 插件轻松实现浮动联系表单
  • AI一周事件(2025年8月6日-8月12日)
  • [ Mybatis 多表关联查询 ] resultMap