linux嵌入式开发:基于linux的语音机器人(五)|LCD显示颜色|LCD显示图片

⭐️ 在本文中主要复习一下LCD屏显示颜色和图片

LCD显示颜色

LCD屏介绍

项目中所运用到了LCD屏是群创 AT070TN92-7 英寸液晶显示屏缺省的可见分辨率为800 * 480, 缺省的虚拟分辨率为 800*960,其在横向长度上有 800 个像素点, 在纵向宽度上有 480 个像素点, 色彩深 度 BPP 是 32 位真彩色, 分别是保留、红、绿、蓝,只要在这四个字节上填充相应的数据, 就可以控制该像素点显现不同的颜色

软件设计

step1:打开显示器,调用open函数去打开显示器的文件(/dev/fb0)
step2:write写入颜色的数值到显示器中,就能显示颜色
step3:关闭显示器

编辑程序

#include<stdio.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<unistd.h>  //write、close函数的头文件
int main(int argc,char *argv[])
{
    //第一步:打开显示屏(/dev/fb0)
    int fd_fb0=open("/dev/fb0",O_RDWR);
    if(-1==fd_fb0){
        printf("显示器打开失败\n");
    }
    else{
        printf("显示器打开成功,文件描述符的数值:%d\n",fd_fb0);
    }
    //第二步:write写入颜色的数值到显示器中,就能显示颜色
    //数据源头就是整形数据,显示一个像素的数据是32位真彩色数据
    //32bits=4Bytes,即ARGB
    //例如显示红色:            00000000 11111111 00000000 00000000
    //以十六进制表示颜色数值: 0x   00       ff       00      00  
    unsigned int color=0x00ff0000;  //显示红色
    //因为LCD屏幕的像素点是800 * 480,所以要通过for循环来连续写入像素点
    //写入之后就可显示颜色
    int i=0;
    for(i=0;i<800*480;i++){
        //数据源color是一个整型数据,write写的时候void *buf指的是任意指针,所以要让该变量取地址
        write(fd_fb0,&color,sizeof(color));
   
    }
    //第三步,写完数据后关闭文件
    close(fd_fb0);
    return 0;
}

编译程序

下载到目标板

⭐️与之前不同的是,在显示图片这个功能,我们不仅要下载程序到目标板中,还要下载文件夹和图片到目标板中,下面进行详细说明
⭐️从任务管理器输入密码进入后,下载好程序后,下面来说明下载图片的操作

首先要在开发板中创建image文件夹,用以存放下载的图片

在这里插入图片描述

创建好文件夹后,就要下载图片啦,需要注意的有两点
第一,tftp需设置好图片所在的image文件
第二,我们需要在任务管理器中进入image文件夹,再来进行下载程序,这样才是和程序中的图片地址相符

在这里插入图片描述

当所有图片都下载完成后,在更改tftp软件的文件配置,将其改成main所在的文件夹下,再执行程序

仿真测试

系统调试

⭐️ 以上步骤省略,与上一篇的文章步骤相同,唯一需要注意的是在下载程序到目标板的过程中需要注意 更改tftp的文件地址,否则将会下载失败,还要注意 ip地址

LCD显示图片

BMP图片介绍

采用位映射存储格式,除了图像深度可选以外,不采用其他任何压缩,因此, BMP文件所占用的空间很大

文件的图像深度可选lbit、4bit、8bit及24bit

BMP 文件存储数据时,图像的扫描方式是按从左到右、从下到上的顺序

BMP文件组成: BMP文件由文件头、位图信息头、颜色信息和图形数据四部分组成
文件头(14字节): BMP文件头数据结构含有BMP文件的类型、文件大小和位图起始位置等信息
位图信息头(40字节):BMP位图信息头数据用于说明位图的尺寸等信息。

颜色表:颜色表用于说明位图中的颜色,它有若干个表项,每一个表项是一个RGBQUAD 类型的结构,定义一种颜色

结构体如下所示

//位图数据位图数据记录了位图的每一个像素值,记录顺序是在扫描行内是从左到右,扫描 行之间是从下到上
//位图的一个像素值所占的字节数: 
//当biBitCount=1时,8个像素占1个字节; 
//当biBitCount=4时,2个像素占1个字节; 
//当biBitCount=8时,1个像素占1个字节; 
//当biBitCount=24时,1个像素占3个字节,按顺序分别为B,G,R,我们使用就是24位位图
typedef struct tagRGBQUAD{
	BYTE rgbBlue;			//蓝色的亮度(值范围为0-255)
	BYTE rgbGreen;			//绿色的亮度(值范围为0-255)
	BYTE rgbRed;			//红色的亮度(值范围为0-255)
	BYTE rgbReserved;		//保留,必须为0 
}__attribute__((packed)) RGBQUAD; 

软件设计

如何显示BMP图片?
1、设置一张分辨率为800*480大小的且位深度为24位的.bmp格式的图片
2、使用open函数打开bmp图片
3、使用open函数打开LCD设备文件
4、跳过bmp格式特有的54字节
5、把bmp格式的RGB数据读取到一个buf中
6、通过24位转32位的方法进行数据转换
7、由于扫描方式不同,需要进行翻转
8、把最后的数据写入到LCD中
9、关闭对应的设备文件

编辑程序

#include<stdio.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<unistd.h>  //write、close函数的头文件
int main(int argc,char *argv[])
{
    //1、设置一张分辨率为800*480大小的且位深度为24位的.bmp格式的图片  
    //2、使用open函数打开bmp图片---->打开硬盘中的图片
    int fd_bmp=open("./image/1.bmp",O_RDWR);    //image文件夹下的bmp文件
    if(-1==fd_bmp){
        printf("图片打开失败\n");
    }
    else{
        printf("图片打开成功,文件描述符的数值:%d\n",fd_bmp);
    }

    //3、使用open函数打开LCD设备文件--->打开显示器
    int fd_fb0=open("/dev/fb0",O_RDWR);
    if(-1==fd_fb0){
        printf("打开显示屏失败\n");
    }
    else{
        printf("打开显示屏成功,文件描述符的数值:%d\n",fd_fb0);
    }

    //4、跳过bmp格式特有的54字节--->让光标的位置从开头的位置偏移54个字节,就是跳过图片的文件头(14字节)和位图信息头(40字节)
    //fd_bmp:文件描述符;54:偏移量;SEEK_SET:表示基点,即从文件开头开始偏移
    lseek(fd_bmp,54,SEEK_SET);

    //5、把bmp格式的RGB数据读取到一个buf中
    //用read函数读取图片,有多少像素就读到buf中
    //在BMP格式中,1个像素点是3个字节,按顺序分别是BGR,因此共有800*480*3
    unsigned char bmp_buf[800*480*3]={0};   //字符型一维数组
    read(fd_bmp,bmp_buf,sizeof(bmp_buf));

    //6、通过24位转32位的方法进行数据转换 
    //32位------>显示器显示1个像素  ARGB
    unsigned int lcd_buf[800*480]={0};  //存储转换后的32位显示器数据
    bmp_buf[800*480*3]                  //上文的图片存储24位的数据
    //在bmp图片中:一个像素存储在三个数组中 bmp_buf[0]:B;bmp_buf[1]:G;bmp_buf[2]:R  1个char类型数组1个字节,3个共24位
    //在LCD中:一个像素存储在一个数组中 lcd_buf[0]:ARGB                             1个int类型数组4个字节,共表示32位
    //所以要想合并在一起,就要将bmp_buf[0]左移0位、bmp_buf[1]左移8位、bmp_buf[2]左移16位
    lcd_buf[0]=bmp_buf[0]<<0|bmp_buf[1]<<8|bmp_buf[2]<<16;
    //800*480个像素点
    int i=0;
    for ( i = 0; i < 800*480; i++)
    {
        lcd_buf[i]=bmp_buf[i*3+0]<<0|bmp_buf[i*3+1]<<8|bmp_buf[i*3+2]<<16;
    }

    //7、由于扫描方式不同,需要进行翻转,即图片在LCD中的显示是反转的,我们需要将其正面显示
    int tmp_buffer[800*480];
	for(y=0;y<480;y++) 
    {
        for(x=0;x<800;x++) 
		{
            tmp_buffer[(479-y)*800+x] = lcd_buf[y*800+x]; 
        }
    }
        
    //8、把最后的数据写入到LCD中  
    //写入数据要将光标从最前面开始写,即配置显示器的光标
    lseek(fd_fb0,0,SEEK_SET);
    int j=0;
    for(j=0;j<800*480;j++){
        write(fd_fb0,&tmp_buffer[j],sizeof(tmp_buffer));
    }

    //9、关闭对应的设备文件
    close(fd_bmp);
    close(fd_fb0);
    return 0;
}

编译程序

下载软件到目标板

仿真调试

系统调试

⭐️ 以上步骤都讲过啦~~~,重要的是程序是怎么编的,编译的思路都是一样哒~

图片的设置

利用电脑自带画图软件将图片的大小匹配显示800x480,以便后续像素压缩为800x480时图片不会变形
保存时需要将图片另保存为24位位图

在这里插入图片描述

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值