利用framebuffer在显示设备中显示图片和文字

一、显示图片

显示图片的函数:


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);
}
  1. 函数参数

    • int x, int y:指定图像绘制的起始坐标(左上角)在屏幕上的位置。
    • char *pic:BMP 文件的路径。
    • int w, int h:图片的宽度和高度。
  2. 打开文件

    • 使用 open 函数打开指定的 BMP 图片文件。如果打开失败,程序会通过 perror 输出错误信息并返回。
  3. 分配内存

    • 使用 malloc 函数分配一段内存,大小为 w * h * 3 字节(因为每个像素占用 3 个字节,分别为 R、G、B 三个颜色分量)。
  4. 读取图像数据

    • 使用 lseek 函数移动文件指针到文件的第 54 字节,跳过 BMP 文件头(前 54 字节通常用于存储 BMP 文件的一些元数据)。然后,使用 read 函数读取图片数据到 buf 中。
  5. 绘制图像

    • 图片数据是从底部到顶部存储的(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:表示字符的背景色(绘制点的颜色,但在代码中并未使用)。
流程:
  1. 字符转换

    • 将 UTF-8 字符转换为 Unicode 字符,存储在变量 out 中。
  2. 获取字符数据

    • 调用 get_utf_data 函数获取对应的像素表示数据,数据存储在 data 中。
  3. 绘制字符

    • 使用三重循环遍历字符的每一行和每一列:
      • 外循环遍历字符的高度。
      • 中循环遍历字符的宽度(以 8 个比特为一组,假设每个字节表示 8 个像素)。
      • 内循环遍历 8 位像素(每个比特)。
    • 检查当前比特位是否为 1(如果在数据中为 0x80,则表示该像素需要绘制):
      • 如果为 1,则调用 draw_point 函数在指定坐标绘制像素。
  4. 返回结果

    • 函数返回 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:字符背景色(未使用)。
流程:
  1. 初始化指针和坐标

    • 使用 temp 指针遍历字符串,初始化显示坐标(x 和 y)。
  2. 逐个字符绘制

    • 使用 while 循环遍历字符串字符,直到碰到字符串结束符:
      • 调用 display_show_utf8 方法显示当前字符。
      • 更新 x 坐标,按字符宽度调整位置。如果 x 坐标超出显示区域宽度,则重置为 0,并将 y 坐标增加字符高度。
      • 如果 y 超出显示区域高度,则将 y 重新开始计数(设为 0)。
  3. 返回结果

    • 函数返回 0。

 

  • 6
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值