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

Linux学习-UI技术

UI技术:User interface

framebuffer:帧缓冲,帧缓存技术,Linux内核专门为图形化显示提供的一套应用程序接口

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  打开) 
-offset  :映射起始偏移(通常填  0 ,从文件/设备起始位置开始;需是页大小整数倍) 

返回值

- 成功:返回实际映射到的用户空间首地址( void*  类型,可强转为需求指针)
- 失败:返回  MAP_FAILED (本质是  (void *)-1 ,需用  perror  等排查错误)

munmap

int munmap(void *addr, size_t length);  

解除映射

功能

- 释放  mmap  建立的内存映射关系,回收映射的虚拟地址空间,避免内存泄漏。
- 调用后,原映射区域的指针( addr  起始的  length  空间)不可再访问,否则会触发段错误。

参数

 addr   mmap  :返回的映射首地址(必须精准匹配,否则可能导致未定义行为) 
length  :映射的空间大小(需与  mmap  时传入的  length  一致,确保完整解除) 

返回值

- 成功:返回  0 
- 失败:返回  -1 ,可通过  errno  查具体错误(如非法地址、权限问题等)

头文件

#ifndef __FRAMEBUFF_H__
#define __FRAMEBUFF_H__#define RGB_FMT_888 32
#define RGB_FMT_565 16#pragma pack(1)// bmp文件相关信息
typedef struct tagBITMAPFILEHEADER
{short bfType;       // 文件类型标志int bfSize;         // 文件大小,单位为字节short bfReserved1;  // 保留字节short bfReserved2;  // 保留字节int bfOffBits;      // 数据偏移量,即实际图像数据开始的位置
} Bmp_file_head_t;
// bmp图像信息
typedef struct tagBITMAPINFOHEADER
{int biSize;           // BITMAPINFOHEADER的大小,单位为字节int biWidth;          // 位图的宽度,单位为像素int biHeight;         // 位图的高度,单位为像素short biPlanes;       // 目标设备的位平面数,必须为1short biBitCount;     // 每像素位数(颜色深度)int biCompression;    // 图像压缩类型int biSizeImage;      // 图像大小,单位为字节int biXPelsPerMeter;  // 水平分辨率,单位为像素/米int biYPelsPerMeter;  // 垂直分辨率,单位为像素/米int biClrUsed;        // 实际使用颜色数int biClrImportant;   // 重要颜色数
} Bmp_info_t;
#pragma pack()extern int init_fb(char *devname);
extern int uninit_fb();
extern void draw_point(int x, int y, unsigned int col);
extern int DrawXLine(int x, int y, int len, unsigned int col);
extern int DrawYLine(int x, int y, int len, unsigned int col);
extern int DrawRect(int x, int y, int high, int wide, unsigned int col);
extern int DrawCircle(int x, int y, int r, unsigned int col);
extern void draw_bmp(int x, int y, char *bmpname);
extern void draw_word(int x, int y, unsigned char *pword, int w, int h,unsigned int col);
#endif

配置framebuffer

#include "framebuff.h"
#include <fcntl.h>
#include <linux/fb.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.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);
}

绘制点

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;}
}

绘制横线

int DrawXLine(int x, int y, int len, unsigned int col)
{int i = 0;for (i = 0; i < len; i++){draw_point(x + i, y, col);}return 0;
}

绘制竖线

int DrawYLine(int x, int y, int len, unsigned int col)
{int i = 0;for (i = 0; i < len; i++){draw_point(x, y + i, col);}return 0;
}

绘制矩形框

int DrawRect(int x, int y, int high, int wide, unsigned int col)
{DrawXLine(x, y, wide, col);DrawYLine(x, y, high, col);DrawYLine(x + wide, y, high, col);DrawXLine(x, y + high, wide, col);return 0;
}

绘制圆

int DrawCircle(int x, int y, int r, unsigned int col)
{int i, a, b;for (i = 0; i < 360; ++i){a = x + r * cos(i / 180.0 * M_PI);b = y + r * sin(i / 180.0 * M_PI);draw_point(a, b, col);}
}

绘制图片bmp格式

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.txt.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);
}

绘制文字(需要取模软件)

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;}}}
}

主函数调用

#include <stdio.h>
#include "framebuff.h"/*
1. 打开显示设备(/dev/fb0)
2. 获取显示设备相关参数(分辨率,像素格式)
3. 建立显存空间和用户空间的内存映射
4. 向映射的用户空间写入RGB颜色值
5. 解除映射关系
6. 关闭显示设备
*/
unsigned char p[4 * 33] = {/*--  文字:  辉  --*//*--  仿宋24;  此字体下对应的点阵为:宽x高=32x33   --*//*--  文字:  辉  --*//*--  仿宋24;  此字体下对应的点阵为:宽x高=32x33   --*/0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xC0,0x00, 0x00, 0x00, 0xE0, 0x00, 0x18, 0x00, 0xE1, 0x80, 0x3C,0x00, 0xCD, 0xFF, 0xFC, 0x00, 0xCD, 0xFF, 0xF8, 0x1C, 0xCF,0x98, 0x70, 0x0E, 0xDF, 0x9C, 0x60, 0x0E, 0xDB, 0x9C, 0x00,0x07, 0xF8, 0x19, 0xE0, 0x06, 0xF1, 0xFF, 0xF0, 0x00, 0xC1,0xFC, 0x00, 0x00, 0xFF, 0x7C, 0x00, 0x3F, 0xFF, 0x7E, 0x00,0x3F, 0xF0, 0xEE, 0x00, 0x03, 0xF0, 0xEF, 0xE0, 0x03, 0xF1,0xFF, 0xF0, 0x03, 0xF1, 0xFE, 0x00, 0x03, 0x70, 0x8E, 0x00,0x07, 0x70, 0x0E, 0x00, 0x07, 0x76, 0x1F, 0xFC, 0x07, 0x7F,0xFF, 0xFC, 0x06, 0x79, 0xCE, 0x00, 0x0E, 0x78, 0x0E, 0x00,0x0C, 0x70, 0x0E, 0x00, 0x1C, 0x20, 0x0E, 0x00, 0x18, 0x00,0x0E, 0x00, 0x30, 0x00, 0x0E, 0x00, 0x20, 0x00, 0x0E, 0x00,0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00, 0x00};
int main(void)
{int ret = init_fb("/dev/fb0");if (ret < 0){return -1;}// 4. 向映射的用户空间写入RGB颜色值draw_point(400, 300, 0x00FF0000);// DrawXLine(200, 200, 400, 0x00ff0000);// DrawYLine(200, 200, 400, 0x00ff0000);// DrawRect(0, 0, 400, 400, 0x00FF0000);// DrawCircle(200, 200, 200, 0x00FF0000);draw_bmp(0, 0, "./1.txt.bmp");draw_word(400, 300, p, 4, 33, 0x00FFff00);uninit_fb();return 0;
}

补充:

perror函数可打印系统给出的错误信息

http://www.lryc.cn/news/620283.html

相关文章:

  • phpstudy搭建pikachu
  • 《探索C++ set与multiset容器:深入有序唯一性集合的实现与应用》
  • java中的各种引用
  • C++算法·递推递归
  • 从感知到执行:人形机器人低延迟视频传输与多模态同步方案解析
  • 飞算AI:企业智能化转型的新引擎——零代码重塑生产力
  • 音频重采样使用RandomOverSampler 还是 SMOTE
  • Python 基础语法(一)
  • Java研学-RabbitMQ(七)
  • 云计算-实战 OpenStack 私有云运维:服务部署、安全加固、性能优化、从服务部署到性能调优(含数据库、内核、组件优化)全流程
  • 《深入解析C++中的Map容器:键值对存储的终极指南》
  • FPGA+护理:跨学科发展的探索(四)
  • Java 大视界 -- 基于 Java 的大数据可视化在能源互联网全景展示与能源调度决策支持中的应用
  • Ubuntu24.04桌面版安装wps
  • 20250813比赛总结
  • Centos 用户管理
  • 在CentOS 7上配置Android USB网络共享方式的方法
  • 「数据获取」《中国海洋生态环境状况公报》(2001-2023年)(获取方式看绑定的资源)
  • 【linux】--U盘挂载
  • 更友好的并发库conc介绍
  • java集合之单列集合
  • 基于离散余弦变换的激活水印(DCT-AW)
  • TCP Socket 编程实战:实现简易英译汉服务
  • Devextreme-vue + Vue2日历下拉框的使用
  • MySQL优化常用的几个方法
  • 《量子雷达》第3章 量子雷达的传输与散射 预习2025.8.13
  • 上下文工程
  • Spring Boot 整合 Thymeleaf 模板引擎:从零开始的完整指南
  • Qwen大模型加载与文本生成关键参数详解
  • lesson37:MySQL核心技术详解:约束、外键、权限管理与三大范式实践指南