什么是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,宽600
	UnInitFb();
	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_info

	int main(void) {
	    InitFb("/dev/fb0"); // 初始化帧缓冲设备
	
	    // 以下代码段被注释掉了,不会被执行
	    bzero(&utf8_info, sizeof(UTF8_INFO)); // 将 utf8_info 清零
	    strcpy(utf8_info.path, ZIKUK_FILE_BIG); // 设置 utf8_info 的路径为 ZIKUK_FILE_BIG
	    utf8_info.width = 32; // 设置 utf8_info 的宽度为 32
	    utf8_info.height = 32; // 设置 utf8_info 的高度为 32
	    init_utf8(&utf8_info); // 初始化 utf8_info
	
	    DrawBmp("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_info
	
	    UnInitFb(); // 反初始化帧缓冲设备
	
	    return 0; 
	}
}

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

机器学习概论—增强学习

机器学习概论—增强学习 强化学习(Reinforcement Learning, RL)或者说是增强学习,是机器学习的一个领域,旨在使智能体通过与环境的交互学习如何做出决策,它是关于在特定情况下采取适当的行动来最大化奖励。它被各种软件和机器用来寻找在特定情况下应采取的最佳行为或路径…

Unity类银河恶魔城学习记录11-7 p109 Aplly item modifiers源代码

Alex教程每一P的教程原代码加上我自己的理解初步理解写的注释&#xff0c;可供学习Alex教程的人参考 此代码仅为较上一P有所改变的代码 【Unity教程】从0编程制作类银河恶魔城游戏_哔哩哔哩_bilibili ItemData_Equipment.cs using System.Collections; using System.Collecti…

第三篇:3.2 广告可见性 - IAB与MRC及《增强现实广告效果测量指南1.0》

翻译计划 第一篇 概述—IAB与MRC及《增强现实广告效果测量指南》之目录、适用范围及术语第二篇 广告效果测量定义和其他矩阵之- 3.1 广告印象&#xff08;AD Impression&#xff09;第三篇 广告效果测量定义和其他矩阵之- 3.2 可见性 &#xff08;Viewability&#xf…

计算机视觉的应用26-关于Fast-R-CNN模型的应用场景,Fast-R-CNN模型结构介绍

大家好&#xff0c;我是微学AI&#xff0c;今天给大家介绍一下计算机视觉的应用26-关于Fast-R-CNN模型的应用场景&#xff0c;Fast-R-CNN模型结构介绍。Fast R-CNN是一种深度学习模型&#xff0c;主要用于目标检测任务&#xff0c;尤其适用于图像中物体的识别与定位。该模型在基…

【Qt】常用控件(输入类)

目录 一、Line Edit二、Text Edit三、ComBo四、DateTimeEdit五、Slider 一、Line Edit QLineEdit 用来表示单行输入框&#xff0c;可以输入一段文本&#xff0c;但是不能换行。 属性说明test输入框中的文本inputMask输入内容格式约束maxLength最大长度frame是否添加边框echoM…

政安晨:专栏目录【TensorFlow与Keras机器学习实战】

政安晨的个人主页&#xff1a;政安晨 欢迎 &#x1f44d;点赞✍评论⭐收藏 收录专栏: TensorFlow与Keras机器学习实战 希望政安晨的博客能够对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出指正&#xff01; 本篇是作者政安晨的专栏《TensorFlow与Keras机器…

【职场攻略】撰写求职信的艺术:如何用AI技术让你脱颖而出

AI与求职的完美结合&#xff1a;会话式AI产品如何助力你的求职之路&#xff1f; 在当今竞争激烈的求职市场中&#xff0c;一封精心准备的求职信可以为你打开通往理想工作的大门。一封好的求职信不仅能展示你的专业技能和工作经验&#xff0c;还能体现你对职位的热情和对公司文化…

labelme AI 模型运用

一、lebelme 1、界面介绍 点击上图位置&#xff0c;选择对应的模型。这里我每个模型都测试了一下&#xff0c;EfficientSam这个模型最好用&#xff0c;准确率和速度都ok。 2、使用方法 目标框标注方法&#xff1a;点左上角【编辑】-> 【Create Ai-Mask】就可以标志了&…

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

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

AXS2003B 爱协生 2.4W单通道 AB类音频功率放大器 兼容LM4890 低成本

AXS2003B 是一颗单通道AB类音频功率放大器。在5V电源供电&#xff0c;THDN10%&#xff0c;4欧姆负载上可以输出2.4W 的功率。 AXS2003B优异的噪声和THD指标可以提供高品质的音频信号放大。极少的外围元件就能提供芯片稳定工作&#xff0c;大大减少了PCB面积并降低成本。 AXS20…

SSL证书一年多少钱?有便宜的吗?

SSL安全证书的价格因其类型、品牌、验证级别、附加功能&#xff08;如多域名支持、通配符功能等&#xff09;以及购买时长&#xff08;通常以年为单位&#xff09;的不同而有所差异。以下是大致的价格范围&#xff1a; 永久免费SSL证书_永久免费https证书_永久免费ssl证书申请…

广告买量的数据驱动策略:从归因到精准投放

在广告买量场景下&#xff0c;数据驱动一定是有意义的。对中小型企业和产品而言&#xff0c;起量和精准是重点&#xff0c;毕竟他们更关注ROI&#xff08;短期利润&#xff09;&#xff0c;这也是效果广告专注中小型企业的原因。而大企业的核心是把流量合理导入自身构建的生态中…

哲学家带你深♂入了解文件操作

目录 一、文件指针 二、文件的打开与关闭 三、顺序读写函数的介绍 四、文件的随机读写 1、fseek 2、ftell 3、rewind 总结 前言 c语言中的文件操作虽然不怎么常用但也是非常重要的知识&#xff0c;今天由本哲学家带大家深♂入了解c语言文件操作。 一、文件指针 每个被使用的文…

Day24:回溯法 LeedCode 77.组合

回溯法解决的问题都可以抽象为树形结构 for循环就是遍历集合区间&#xff0c;可以理解一个节点有多少个孩子&#xff0c;这个for循环就执行多少次。 从图中看出for循环可以理解是横向遍历&#xff0c;backtracking&#xff08;递归&#xff09;就是纵向遍历&#xff0c;这样就把…

virtualbox 日常运维

前言 虽然平常以macOS和Linux作为主打工作环境&#xff0c;但还是有很多需要用到windows的时候&#xff0c;如camtasia和券商QMT软件。 在二手ThinkPad P53上安装了几个windows虚机&#xff0c;作为测试环境。Mac笔记本远程桌面连接嫌麻烦&#xff0c;还是命令行舒服。MacOS自…

SAP gui 组服务器 提示 Error service sapmsPRD unknown

/etc/hosts 追加IP地址和域名的配对关系 /etc/services 追加 sapms[sid] 3601/tcp

java 抠取红色印章(透明背景)

一个亲戚让我帮他把照片里的红色印章抠出来&#xff0c;&#xff0c;&#xff0c;记录下处理过程&#xff0c;代码如下&#xff0c;可直接用&#xff1a; public static void signatureProcess(String sourceImagePath, String targetImagePath) {Graphics2D graphics2D null…

2015年认证杯SPSSPRO杯数学建模B题(第二阶段)替换式密码全过程文档及程序

2015年认证杯SPSSPRO杯数学建模 B题 替换式密码 原题再现&#xff1a; 历史上有许多密码的编制方法。较为简单的是替换式密码&#xff0c;也就是将文中出现的字符一对一地替换成其它的符号。对拼音文字而言&#xff0c;最简单的形式是单字母替换加密&#xff0c;也就是以每个…

Nodejs 16与 gitbook搭建属于你自己的书本网站-第一篇

最近想重新搭建一个网站来存放自己的相关知识点&#xff0c;并向网络公开&#xff0c;有个hexo博客其实也不错的&#xff0c;但是总感觉hexo很多花里胡哨的玩意&#xff0c;导致挂载的博客异常卡&#xff0c;这样反而不利于我自己回顾博客了&#xff0c;于是我就开始钻研这个鬼…

Android逆向-数据修改逻辑修改视图修改

目录 0x00 相关工具及环境 0x01 APP逆向 - 数据修改 0x02 APP逆向 - 逻辑修改 0x03 APP逆向 - 视图修改 希望和各位大佬一起学习&#xff0c;如果文章内容有错请多多指正&#xff0c;谢谢&#xff01; 个人博客链接&#xff1a;CH4SER的个人BLOG – Welcome To Ch4sers B…