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

Linux Framebuffer(帧缓冲)与基本 UI 绘制技术

1. UI 技术简介

UI(User Interface):用户界面技术,用于实现图形化交互。

在 Linux 中,**framebuffer(帧缓冲/帧缓存)**是内核提供的一套图形显示接口,使用户程序可以直接操作显存实现显示效果。


2. 帧缓冲基础

分辨率

800 × 600

像素格式

格式字节数说明
RGB8883 → 4每个像素 3 个字节,通常对齐到 4 字节
RGB5652每个像素 2 个字节

显存访问示例

unsigned int *pmem;

*(pmem + 800 * y + x) = 0x00FF0000; // 将 (x,y) 位置像素设为红色


3. framebuffer 使用流程

  1. 打开显示设备

int fd = open("/dev/fb0", O_RDWR);

  1. 获取显示参数

ioctl(fd, FBIOGET_VSCREENINFO, &vinfo); // 获取分辨率、像素格式等信息

  1. 建立显存和用户空间的内存映射

void *addr = mmap(NULL, length, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);

参数说明

  • addr:用户空间首地址,NULL 由系统分配

  • length:映射长度

  • prot:访问权限,如 PROT_READ | PROT_WRITE

  • flags:映射类型,如 MAP_SHARED

  • fd:设备文件描述符

  • offset:从显存的偏移量,一般为 0

返回值

  • 成功:映射的用户空间首地址

  • 失败:MAP_FAILED ((void *)-1)

  1. 写入像素数据

    • 向映射的内存写入颜色值即可实现绘图

    • 示例:*(pmem + 800*y + x) = 0x00FF0000;

  2. 解除映射

munmap(addr, length);

  1. 关闭显示设备

close(fd);


4. 基本绘图封装函数

  1. 绘制横线

  2. 绘制竖线

  3. 绘制矩形

  4. 绘制圆

  5. 绘制 BMP 图片

  6. #include <stdio.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    #include <unistd.h>
    #include <stdlib.h>
    #include <sys/ioctl.h>
    #include <linux/fb.h>
    #include <sys/mman.h>
    #include "framebuffer.h"
    #include <math.h>void *pmem = NULL;
    int fb;
    struct fb_var_screeninfo vinfo;int init_fb(char *devname)
    {//1. 打开显示设备(/dev/fb0)fb = open(devname, O_RDWR);if (-1 == fb){perror("open fb error");return -1;}//2. 获取显示设备相关参数(分辨率,像素格式)int ret = ioctl(fb, FBIOGET_VSCREENINFO, &vinfo);if (ret < 0){perror("ioctl error");return -1;}printf("xres = %d, yres = %d\n", vinfo.xres, vinfo.yres);printf("xres_virtual = %d, yres_virtual = %d\n", vinfo.xres_virtual, vinfo.yres_virtual);printf("bits_per_pixel = %d\n", vinfo.bits_per_pixel);//3. 建立显存空间和用户空间的内存映射size_t len = vinfo.xres_virtual * vinfo.yres_virtual * vinfo.bits_per_pixel/8;pmem = mmap(NULL, len, PROT_READ|PROT_WRITE, MAP_SHARED, fb, 0);if (pmem == MAP_FAILED){perror("mmap error");return -1;}return 0;
    }int uninit_fb()
    {//5. 解除映射关系//6. 关闭显示设备size_t len = vinfo.xres_virtual * vinfo.yres_virtual * vinfo.bits_per_pixel/8;munmap(pmem, len);close(fb);return 0;
    }void draw_point(int x, int y, unsigned int col)
    {if (x >= vinfo.xres || y >= vinfo.yres){return ;}if (vinfo.bits_per_pixel == RGB_FMT_888){unsigned int *p = pmem;*(p+vinfo.xres_virtual *y+x) = col;}else if (vinfo.bits_per_pixel == RGB_FMT_565){unsigned short *p = pmem;*(p+vinfo.xres_virtual*y+x) = col;}
    }void draw_row_line(int x, int y, unsigned int col)
    {if (x >= vinfo.xres || y >= vinfo.yres){return ;}if (vinfo.bits_per_pixel == RGB_FMT_888){unsigned int *p = pmem;while(x != 799){*(p+vinfo.xres_virtual *y+x) = col;++x;}}else if (vinfo.bits_per_pixel == RGB_FMT_565){unsigned short *p = pmem;while(x != 799){*(p+vinfo.xres_virtual*y+x) = col;++x;}}
    }void draw_clos_line(int x, int y, unsigned int col)
    {if (x >= vinfo.xres || y >= vinfo.yres){return ;}if (vinfo.bits_per_pixel == RGB_FMT_888){unsigned int *p = pmem;while(y != 599){// *(p+vinfo.xres_virtual*y+x) = col;// ++x;*(p+vinfo.xres_virtual*y+x) = col;++y;}}else if (vinfo.bits_per_pixel == RGB_FMT_565){unsigned short *p = pmem;while(y != 599){// *(p+vinfo.xres_virtual*y+x) = col;// ++x;*(p+vinfo.xres_virtual*y+x) = col;++y;}}
    }void draw_round(int cx, int cy, int r,unsigned int col)
    {if (cx >= vinfo.xres || cy >= vinfo.yres){return ;}if(r > cx || r > cy || r + cx > vinfo.xres || r + cy > vinfo.yres){return ;}double PI = 3.1415926;if (vinfo.bits_per_pixel == RGB_FMT_888){for(double angle = 0;angle <2 * PI;angle += 0.01){int x = (int)(cx + r * cos(angle));int y = (int)(cy + r * sin(angle));draw_point(x, y, col);}}else if (vinfo.bits_per_pixel == RGB_FMT_565){for(double angle = 0;angle < 2 * PI;angle += 0.01){int x = (int)(cx + r * cos(angle));int y = (int)(cy + r * sin(angle));draw_point(x, y, col);}}
    }int get_bmp_head_info(const char *bmpname, Bmp_file_head_t *pheadinfo, Bmp_info_t *pbmpinfo)
    {FILE *fp = fopen(bmpname, "r");if (NULL == fp){perror("fopen error");return -1;}fread(pheadinfo, sizeof(Bmp_file_head_t), 1, fp);fread(pbmpinfo, sizeof(Bmp_info_t), 1, fp);fclose(fp);return 0;
    }void draw_bmp(int x, int y, char *bmpname)
    {Bmp_file_head_t headinfo;Bmp_info_t bmpinfo;get_bmp_head_info("./1.bmp", &headinfo, &bmpinfo);int fd = open(bmpname, O_RDONLY);if (-1 == fd){perror("open bmp error");return ;}lseek(fd, 54, SEEK_SET);unsigned char *buff = malloc(bmpinfo.biHeight*bmpinfo.biWidth*bmpinfo.biBitCount/8);read(fd, buff, bmpinfo.biHeight*bmpinfo.biWidth*bmpinfo.biBitCount/8);close(fd);unsigned char *p = buff;unsigned char r, g, b;for (int j = bmpinfo.biHeight-1; j >= 0; j--){for (int i = 0; i < bmpinfo.biWidth; i++){b = *p;++p;g = *p;++p;r = *p;++p;if (vinfo.bits_per_pixel == RGB_FMT_888){unsigned int col = (r << 16) | (g << 8) | (b << 0);draw_point(i+x, j+y, col);}else if  (vinfo.bits_per_pixel == RGB_FMT_565){unsigned short col = ((r >> 3) << 11) | ((g >> 2) << 5) | (b >> 3);draw_point(i+x, j+y, col);}}}free(buff);}//w = 2, h = 19
    void draw_word(int x, int y, unsigned char *pword, int w, int h, unsigned int col)
    {for (int j = 0; j < h; j++){for (int i = 0; i < w; i++){unsigned char tmp = pword[i+j*w];for (int k = 0; k < 8; k++){if (tmp & 0x80){draw_point(x+i*8+k, y+j, col);}else{}tmp = tmp << 1;}}}
    }

    绘制文字

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

相关文章:

  • GitHub宕机时的协作方案
  • 力扣 hot100 Day72
  • Transformer开端
  • 有效涂色问题-二维dp
  • C++进阶之lambda三种回调方式性能差异(四百二十七)
  • 【13】Transformers快速入门:Transformers 分词器 (Tokenizer) 实战?
  • 哈希表之两个数组的交集(leetcode349)
  • 智能合约开发全流程实战指南
  • 【LeetCode】4. 寻找两个正序数组的中位数
  • 芯伯乐300kHz降压DC/DC转换器XBL4005:4.5V~40V宽电压范围,5A大电流高效输出
  • 三伍微电子GSR2406 IoT FEM 2.4G PA 射频前端模组芯片
  • 深入解析C语言嵌套结构体的内存管理与操作实践
  • linux_网络层-ip协议
  • [系统架构设计师]信息安全技术基础知识(三)
  • SpringBoot3+ Elasticsearch8 Spring-data-Elasticsearch使用
  • 多模态数据集分级方案设计与实现
  • 容器基础镜像制作
  • ETLCloud批流一体化体现在哪
  • 【Python】Python 函数基本介绍(详细版)​
  • 版图设计学习2_掌握PDK中的层定义(工艺文档精读)
  • DAY39打卡
  • 【运维进阶】管理变量和事实
  • 哥斯拉--安装、使用
  • graf示教界面技术累积
  • 数据结构摘星题库800题笔记 第2章线性表
  • [TG开发]简单的回声机器人
  • Linux信号量和信号
  • 淘汰人工巡检!企业配电室无线测温实战:0布线+240点位同步监控
  • @进程管理工具 - Glances工具详细指南
  • 20250813测试开发岗(凉)面