一、显示图片
显示图片的函数:
void draw_pic(int x,int y,char * pic,int w,int h)
{
int fd = open(pic,O_RDONLY);
if(-1 == fd)
{
perror("open fail\n");
return ;
}
unsigned int r,g,b;
unsigned char * buf = malloc(w*h*3);
lseek(fd,54,SEEK_SET);
read(fd,buf,w*h*3);
unsigned char * p = buf;
for(int j = h -1;j >= 0 ;--j)
{
for(int i = 0; i < w ;++i)
{
b = *p;p++;
g = *p;p++;
r = *p;p++;
if (vinf.bits_per_pixel == RGB888_FMT)
{
unsigned int col = (r << 16) | (g << 8) | (b << 0);
draw_point(i+x, j+y, col);
}
else if (vinf.bits_per_pixel == RGB565_FMT)
{
unsigned short col = ((r >> 3) << 11) | ((g >> 2) << 5) | ((b >> 3) << 0);
draw_point(i+x, j+y, col);
}
}
}
free(buf);
close(fd);
}
-
函数参数:
int x, int y
:指定图像绘制的起始坐标(左上角)在屏幕上的位置。char *pic
:BMP 文件的路径。int w, int h
:图片的宽度和高度。
-
打开文件:
- 使用
open
函数打开指定的 BMP 图片文件。如果打开失败,程序会通过perror
输出错误信息并返回。
- 使用
-
分配内存:
- 使用
malloc
函数分配一段内存,大小为w * h * 3
字节(因为每个像素占用 3 个字节,分别为 R、G、B 三个颜色分量)。
- 使用
-
读取图像数据:
- 使用
lseek
函数移动文件指针到文件的第 54 字节,跳过 BMP 文件头(前 54 字节通常用于存储 BMP 文件的一些元数据)。然后,使用read
函数读取图片数据到buf
中。
- 使用
-
绘制图像:
- 图片数据是从底部到顶部存储的(BMP 格式),所以使用双重循环遍历图像的每一行(从下到上)和每一列(从左到右)。
- 在每次循环中,从
buf
中依次读取每个像素的 B(蓝色)、G(绿色)和 R(红色)分量。 - 根据
vinf.bits_per_pixel
的值判断颜色格式:- 如果是
RGB888_FMT
(8 位每通道),则使用 24 位的颜色表示法,将 R、G、B 分量组合成一个 32 位的颜色值,并调用draw_point
函数绘制该点。 - 如果是
RGB565_FMT
(16 位每像素),则处理 R、G、B 分量以适应 16 位颜色值,并调用draw_point
函数绘制该点。
- 如果是
二、显示文字
int display_show_utf8(UTF8_INFO *info, int x, int y, char* zi, u32 col, u32 col1)
{
unsigned long out = 0 ;
int ret = enc_utf8_to_unicode_one((unsigned char*)zi,&out);
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)
{
draw_point( x+k+j*8, y+i, col);
}
else
{
// draw_point( x+k+j*8, y+i, col1);
}
temp= temp<<1;
}
}
}
return ret;
}
int display_show_utf8_str(UTF8_INFO *info, int arg_x, int arg_y, char* zi, unsigned int col,unsigned int col1)
{
char* temp = zi;
unsigned int x = arg_x ;
unsigned int y = arg_y;
while(*temp != '\0')
{
int ret = display_show_utf8(info, x, y, temp, col, col1);
x += info->width;
if(x > vinf.xres_virtual)
{
x = 0;
y += info->height;
if(y > vinf.yres_virtual)
{
y = 0;
}
}
temp += ret;
}
return 0;
}
1. display_show_utf8
函数
功能:
该函数将一个 UTF-8 编码的字符绘制到指定的位置,支持不同颜色的像素显示。
参数:
UTF8_INFO *info
:包含字体信息(如宽度和高度等)。int x, int y
:字符显示的起始位置坐标。char* zi
:指向 UTF-8 字符的指针。u32 col
:表示字符的前景色(绘制点的颜色)。u32 col1
:表示字符的背景色(绘制点的颜色,但在代码中并未使用)。
流程:
-
字符转换:
- 将 UTF-8 字符转换为 Unicode 字符,存储在变量
out
中。
- 将 UTF-8 字符转换为 Unicode 字符,存储在变量
-
获取字符数据:
- 调用
get_utf_data
函数获取对应的像素表示数据,数据存储在data
中。
- 调用
-
绘制字符:
- 使用三重循环遍历字符的每一行和每一列:
- 外循环遍历字符的高度。
- 中循环遍历字符的宽度(以 8 个比特为一组,假设每个字节表示 8 个像素)。
- 内循环遍历 8 位像素(每个比特)。
- 检查当前比特位是否为 1(如果在数据中为 0x80,则表示该像素需要绘制):
- 如果为 1,则调用
draw_point
函数在指定坐标绘制像素。
- 如果为 1,则调用
- 使用三重循环遍历字符的每一行和每一列:
-
返回结果:
- 函数返回
ret
,这是从 UTF-8 转换过程中返回的结果。
- 函数返回
2. display_show_utf8_str
函数
功能:
该函数用于显示 UTF-8 编码字符串,逐个字符调用 display_show_utf8
函数进行绘制。
参数:
UTF8_INFO *info
:包含字体信息。int arg_x, arg_y
:字符串显示的起始位置坐标。char* zi
:指向 UTF-8 字符串的指针。unsigned int col
:字符前景色。unsigned int col1
:字符背景色(未使用)。
流程:
-
初始化指针和坐标:
- 使用
temp
指针遍历字符串,初始化显示坐标(x
和y
)。
- 使用
-
逐个字符绘制:
- 使用
while
循环遍历字符串字符,直到碰到字符串结束符:- 调用
display_show_utf8
方法显示当前字符。 - 更新
x
坐标,按字符宽度调整位置。如果x
坐标超出显示区域宽度,则重置为 0,并将y
坐标增加字符高度。 - 如果
y
超出显示区域高度,则将y
重新开始计数(设为 0)。
- 调用
- 使用
-
返回结果:
- 函数返回 0。