如何切换到终端模式
在昨天写的文章中,没有写到如何切换到终端模式,在编译完函数之后,我们需要从桌面切换到终端模式:
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;
}
}
结果:
以上就是今天的内容,谢谢!