什么是framebuffer,怎么应用(二)————如何打印BMP图片、字幕函数、字符串

如何切换到终端模式

在昨天写的文章中,没有写到如何切换到终端模式,在编译完函数之后,我们需要从桌面切换到终端模式:

ALT+CTRL+F3

切换到终端模式后,登录账号名与密码,其余操作均有桌面终端一样。
如何切换回:

ATL+CTRL+F1

那么讲完这些,我们该考虑如何打印BMP图片了

BMP图片

首先,BMP图片的数据格式可以分为四个部分:
1.文件头(bmp file header):占14字节,包含文件格式、大小等信息
2.位图信息头(bitmap information):占40字节,包含图片的数据尺寸、颜色索引等信息
3.调色板(color palette):颜色表用于说明位图中的颜色,它有若干个表项,每一个表项定义一种颜色。
4.位图书数据(bitmap data):位图数据记录了位图的每一个像素值。
所以在打印图片时,我们需要让数据向后偏移54个字节的位置进行打印,并且bmp图像是反过来的,当我们偏移到相对位置后,再从图片的最后一行开始,后续会介绍。

打印BMP图片

//BMP图片
void DrawBmp(char *bmpname,int w,int h)	//图片地址、宽度、高度
{int fd = open(bmpname,O_RDONLY);	//只读方式打开if(-1 == fd){perror("fail to open");		//输出错误信息并返回return ;}// 将文件指针移到像素数据的起始位置(跳过BMP文件头)lseek(fd,54,SEEK_SET);	// 分配内存以保存图片的像素数据unsigned char *pic = malloc(w * h * 24 / 8);// 从文件中读取像素数据,一次性读完read(fd,pic,w*h*24/8);unsigned char *p = pic;// 遍历像素数据,绘制图像//BMP 图片的像素数据存储是从图片的底部(最后一行)开始的,而不是从顶部开始,所以i从h-1开始for(int i = h -1;i >= 0;--i){for(int j = 0;j < w;++j){unsigned char r,g,b;// 从像素数据中读取RGB值b = *p;	// 蓝色分量++p;g = *p; // 绿色分量++p;r = *p;	// 红色分量++p;// 根据显示设备的颜色格式,绘制像素点if(fbinfo_g.bits == RGB888_FMT){// 对于RGB888格式,将RGB值组合成一个32位颜色值unsigned int col = r << 16 | g << 8 | b;DrawPoint(j,i,col);}else if(fbinfo_g.bits == RGB565_FMT){// 对于RGB565格式,将RGB值组合成一个16位颜色值unsigned short col = (r >> 3) << 11 | (g >> 2) << 5 | (b >> 3);DrawPoint(j,i,col);}}}free(pic);	// 释放分配的内存close(fd);	// 关闭文件
}int main(void)
{InitFb("/dev/fb0");		//昨天已经解释过,可以看昨天的内容DrawBmp("2.bmp",800,600);	//读取当前路径中2.bmp文件,高800,宽600UnInitFb();return 0;
}

什么是framebuffer,怎么应用(一)————如何画点、线、矩形、圆
结果:
在这里插入图片描述

字符串打印

在打印字符串之前,我们需要一个库函数,我已经将库函数传入资源中,大家可以自行去下载
C用于C和C ++的单头utf8字符串函数

打印

首先将#include "utf.h"放置头文件中,在使用utf之前,我们需要知道utf.c文件中这些函数

utf.h头文件

#ifndef UTF
#define UTF
#ifdef __cplusplus
extern "C"{
#endif
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <stdlib.h>
#include <fcntl.h>
#define u8 unsigned char 
#define u16 unsigned short 
#define u32 unsigned int#define ZIKUK_FILE_SMALL "./ziku"
#define ZIKUK_FILE_BIG "./ziku2_w32_h32"
/***字模文件缓存**/
typedef struct
{char path[256];//字模库文件路径unsigned width; //字模宽度unsigned height;//字模高度unsigned zimo_size;//每个字字模字节数unsigned char* g_ziku_data;//字模库文件缓存区
}UTF8_INFO;extern void init_utf8(UTF8_INFO *info);
extern unsigned char *get_utf_data(UTF8_INFO *info,int out);extern void uninit_utf8(UTF8_INFO *info);
extern int enc_utf8_to_unicode_one(const unsigned char* pInput, unsigned long *Unic);
extern int enc_unicode_to_utf8_one(unsigned long unic, unsigned char *pOutput,int outSize);
extern int enc_get_utf8_size(const unsigned char pInput);#ifdef __cplusplus
}
#endif
#endif // UTF

将字库文件读取到缓存区

函数名:init_utf8将字库文件读取到缓存区
参数:info     需要回收的字模缓存区
返回值:无
注意事项:无
void init_utf8(UTF8_INFO *info)
{int ret = 0 ;int fd = open(info->path,O_RDONLY);if(-1 == fd){exit(1);}struct stat st;ret = stat(info->path,&st);if(-1 == ret){printf("get zi ku file size error");exit(1);}if(NULL == info->g_ziku_data){info->g_ziku_data= malloc(st.st_size);}ret = read(fd,info->g_ziku_data,st.st_size);if(ret<=0){printf("read utf-8 info error!");exit(1);}
//    info->height = heigh;
//    info->width = width;info->zimo_size = st.st_size /65536;close(fd);
}

回收字模缓存区空间

函数名:uninit_utf8回收字模缓存区空间
参数:info     需要回收的字模缓存区
返回值:无
注意事项:无
void uninit_utf8(UTF8_INFO *info)
{free(info->g_ziku_data);
}

打印字符串

UTF-8 字符串

int draw_utf8(UTF8_INFO *info,int x,int y,char *zi,unsigned int col,unsigned int col1)
{unsigned long out = 0;// 将UTF-8编码转换为Unicode码点int ret = enc_utf8_to_unicode_one((unsigned char *)zi,&out);// 获取UTF字体数据unsigned char *data = get_utf_data(info,out);unsigned char temp = 0;unsigned int i,j,k;unsigned int num = 0;for(i = 0;i < info->height;i++){for(j = 0;j < info->width/8;++j){temp = data[num++];for(k = 0;k<8;k++){if(0x80&temp)	//按位与{DrawPoint(x+j*8+k,y+i,col);}else{//DrawPoint(x+j*8+k,y+i,col1);}temp = temp << 1;}}}return ret;
}

main.c

#include "framebuffer.h" // 包含 framebuffer.h 头文件UTF8_INFO utf8_info; // 定义一个 UTF8_INFO 结构体变量 utf8_infoint main(void) {InitFb("/dev/fb0"); // 初始化帧缓冲设备// 以下代码段被注释掉了,不会被执行bzero(&utf8_info, sizeof(UTF8_INFO)); // 将 utf8_info 清零strcpy(utf8_info.path, ZIKUK_FILE_BIG); // 设置 utf8_info 的路径为 ZIKUK_FILE_BIGutf8_info.width = 32; // 设置 utf8_info 的宽度为 32utf8_info.height = 32; // 设置 utf8_info 的高度为 32init_utf8(&utf8_info); // 初始化 utf8_infoDrawBmp("2.bmp", 800, 600); // 绘制 BMP 图像到屏幕sleep(1); // 等待 1 秒draw_utf8_str(&utf8_info, 100, 100, "大家好,我是古天乐,是兄弟就砍我100刀!", 0x00ff0000, 0x00000000); // 在屏幕上绘制 UTF-8 字符串uninit_utf8(&utf8_info); // 反初始化 utf8_infoUnInitFb(); // 反初始化帧缓冲设备return 0; }
}

结果:
请添加图片描述
以上就是今天的内容,谢谢!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/2906286.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

二十九 超级数据查看器 讲解稿 查询复用

二十九 超级数据查看器 讲解稿 查询复用 ​点击此处 以新页面 打开B站 播放当前教学视频 点击访问app下载页面 百度手机助手 下载地址 大家好&#xff0c;今天我们讲一下超级数据查看器的查询复用功能&#xff0c;这是新版本要增加的功能&#xff0c;这讲是预告。 先介绍…

【能省则省】搭建网站仅50/年 云服务器选择建议 程序员职场刚需云产品 附最新价格对比表

《最新对比表》已更新在文章头部—腾讯云文档&#xff0c;文章具有时效性&#xff0c;请以腾讯文档为准&#xff01; 【腾讯文档实时更新】云服务器1分钟教会你如何选择教程 2024-开年采购活动 云服务器专区 京东云 阿里云 腾讯云 配置最新价格表 与 官方活动地址 ​ 当前活动…

【python】爬取4K壁纸保存到本地文件夹【附源码】

欢迎来到英杰社区https://bbs.csdn.net/topics/617804998 图片信息丰富多彩&#xff0c;许多网站上都有大量精美的图片资源。有时候我们可能需要批量下载这些图片&#xff0c;而手动一个个下载显然效率太低。因此&#xff0c;编写一个简单的网站图片爬取程序可以帮助我们…

SpringCloudConfig 使用git搭建配置中心

一 SpringCloudConfig 配置搭建步骤 1.引入 依赖pom文件 引入 spring-cloud-config-server 是因为已经配置了注册中心 <dependencies><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-config-server</…

RPA使用Native Messaging协议实现浏览器自动化

RPA 即机器人流程自动化&#xff0c;是一种利用软件机器人或人工智能来自动化业务流程中规则性、重复性任务的技术。RPA 技术可以模拟和执行人类在计算机上的交互操作&#xff0c;从而实现自动化处理数据、处理交易、触发通知等任务。帮助企业或个人实现业务流程的自动化和优化…

如何缩短职场人与人之间的差距?答案或许就隐藏在一纸社科院与杜兰大学能源管理硕士学位之中

你是否曾惊叹于同事某某的飞速进步&#xff0c;短短两年内连升三级&#xff0c;如同职场上的彗星划破夜空&#xff1f;每当看到他们晋升的喜讯在群里传播&#xff0c;你的内心是否也曾涌起一股难以名状的涟漪&#xff1f;与你一同踏入公司的伙伴&#xff0c;如今已是经理级别&a…

政务AI交互数字人推动政务“人工智能+”建设

传统的政务平台大多是单向与用户互动&#xff0c;缺乏即时反馈&#xff0c;导致用户需要花费大量时间理解信息&#xff0c;并难以提出问题得到及时解答。 AI交互数字人凭借其智能性&#xff0c;可以在政务网页、政务业务办理大厅一体机、政务APP/小程序等终端设备中&#xff0…

零基础如何学Python?这些方法你一定要知道

由于python在人工智能&#xff0c;机器学习&#xff0c;大数据&#xff0c;数据分析&#xff0c;网络爬虫&#xff0c;全方位的技能特点&#xff0c;是非常适合初学者入门和培养编程兴趣的一门语言。相比较其他不少主流编程语言&#xff0c;有更好的可读性和满足感&#xff0c;…

ArcGIS矢量裁剪矢量

一、利用相交工具 Arctoolbox工具一分析工具一叠加分析一相交

多个微信这样高效管理

随着微信成为企业商务沟通的主要平台&#xff0c;一些业务咨询量较大的行业&#xff0c;如教育培训、旅游、美容及医疗等&#xff0c;通过微信开展营销活动和客户服务过程中&#xff0c;经常面临多微信管理难题。 在这种情况下&#xff0c;采用微信线上业务模式&#xff0c;需…

【单调栈】【网格】【柱图面积】85. 最大矩形

作者推荐 视频算法专题 本文涉及的基础知识点 单调栈分类、封装和总结 网格 LeetCode85. 最大矩形 给定一个仅包含 0 和 1 、大小为 rows x cols 的二维二进制矩阵&#xff0c;找出只包含 1 的最大矩形&#xff0c;并返回其面积。 示例 1&#xff1a; 输入&#xff1a;…

Android裁剪图片为波浪形或者曲线形的ImageView

如果需要做一个自定义的波浪效果的进度条&#xff0c;裁剪图片&#xff0c;对ImageView的图片进行裁剪&#xff0c;比如下面2张图&#xff0c;如何实现&#xff1f; 先看下面的效果&#xff0c;看到其实只需要对第一张高亮的图片进行处理即可&#xff0c;灰色状态的作为背景图。…

【多线程系列】你先说说synchronized的实现原理

面试官&#xff1a;听说你精通多线程&#xff0c;那我就考考你吧 面试官&#xff1a;不用慌尽管说&#xff0c;错了也没关系&#x1f60a;。。。 以贴近现实的【面试官面试】形式来分享技术&#xff0c;本期是《多线程系列》&#xff0c;感兴趣就关注我吧❤️ 面试官&#xff1…

vue3开发前端表单缓存自定义指令,移动端h5必备插件

开发背景 公司需要开发一款移动端应用&#xff0c;使用vue开发&#xff0c;用户录入表单需要本地缓存&#xff0c;刷新页面&#xff0c;或者不小心关掉重新进来&#xff0c;上次录入的信息还要存在。 这里有两种方案&#xff0c;第一种就是像博客平台一样&#xff0c;实时保存…

基于kalman的单目标追踪,以及demo测试(Python and C++)

一.卡尔曼滤波简单介绍 我们可以在任何含有不确定信息的动态系统中的使用卡尔曼滤波&#xff0c;对系统的下一步动作做出有根据的猜测。猜测的依据是预测值和观测值&#xff0c;首先我们认为预测值和观测值都符合高斯分布且包含误差&#xff0c;然后我们预设预测值的误差Q和观测…

对form表单对象中数组中的字段进行校验的方法

当对form表单中&#xff0c;数组readings中的字段进行校验时&#xff0c;prop和rules绑定要写成动态的&#xff0c;如下代码 <div v-for"(item,index) in form.readings"><el-form-item label"上次读数" > <!--prop"scds"-->…

R语言赋值符号<-、=、->、<<-、->>的使用与区别

R语言的赋值符号有&#xff1c;-、、-&#xff1e;、&#xff1c;&#xff1c;-、-&#xff1e;&#xff1e;六种&#xff0c;它们的使用与区别如下: <-’&#xff1a;最常用的赋值符号。它将右侧表达式的值赋给左侧的变量&#xff0c;像一个向左的箭头。例如&#xff0c;x …

GitLab更新失败(Ubuntu)

在Ubuntu下使用apt更新gitlab报错如下&#xff1a; An error occurred during the signature verification.The repository is not updated and the previous index files will be used.GPG error: ... Failed to fetch https://packages.gitlab.com/gitlab/gitlab-ee/ubuntu/d…

4、Cocos Creator 动画系统

Animation 组件是节点上的一个组件。Clip 动画剪辑就是一份动画的声明数据&#xff0c;我们将它挂载到 Animation 组件上&#xff0c;就能够将这份动画数据应用到节点上。 1、Clip 参数 1、sample&#xff1a;定义当前动画数据每秒的帧率&#xff0c;默认为 60&#xff0c;这…

【智能家居项目】RT-Thread版本——DHT11获取温湿度 | MQTT上传到服务器 | 服务器控制外设

&#x1f431;作者&#xff1a;一只大喵咪1201 &#x1f431;专栏&#xff1a;《智能家居项目》 &#x1f525;格言&#xff1a;你只管努力&#xff0c;剩下的交给时间&#xff01; 这篇文章中&#xff0c;本喵将使用RT-Thread Studio来实现这个智能家居的项目&#xff0c;最终…