当前位置: 首页 > 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.xdnf.cn/news/1294939.html

相关文章:

  • Python【算法中心 03】Docker部署Django搭建的Python应用流程实例(Docker离线安装配置+Django项目Docker部署)
  • Coze Studio 概览(十)--文档处理详细分析
  • 51单片机-51单片机最小系统
  • Java Stream API 中常用方法复习及项目实战示例
  • 普通电脑与云电脑的区别有哪些?全面科普
  • Apifox精准定义复杂API参数结构(oneOf/anyOf/allOf)
  • Spring Boot项目调用第三方接口的三种方式比较
  • Spring Boot初级概念及自动配置原理
  • LeetCode215~ 234题解
  • 【代码随想录day 19】 力扣 450.删除二叉搜索树中的节点
  • PyTorch简介
  • electron进程间通信- 从渲染进程到主进程
  • [量化交易](1获取加密货币的交易数据)
  • 从0开始跟小甲鱼C语言视频使用linux一步步学习C语言(持续更新)8.13
  • C#自定义日期时间选择器
  • C++中的`auto`与`std::any`:功能、区别与选择建议
  • ResourcelessTransactionManager的作用
  • 嵌入式第二十七天(UI相关技术(framebuffer))
  • 深度学习·ExCEL
  • 基于js和html的点名应用
  • Jenkins一直无法启动,怎么办?
  • C# 反射入门:如何获取 Type 对象?
  • Android平台RTSP播放器选型指南:从开源方案到跨平台低延迟专业SDK
  • 浅层神经网络
  • Mysql——如何做到Redolog崩溃后恢复的
  • 完整源码+技术文档!基于Hadoop+Spark的鲍鱼生理特征大数据分析系统免费分享
  • Linux 软件编程:文件IO、目录IO、时间函数
  • VUE基础笔记
  • JS的学习5
  • 更改webpack默认配置项