一、目标:在lcd液晶屏幕上显示一张24位,分辨率为800*480 bmp格式图片。 1、分析lcd设备的参数。 分辨率:800*480 -> 整个屏幕上像素点的总数 总字节数:800*480*4
lcd屏幕上的每一个像素点都可以显示任何的颜色,因为像素点由三原色组成,分别是RGB,只需要把对应的颜色,放在对应的位置就可以。 每一个像素点: ARGB -> 透明度,红色,绿色,蓝色 0x00FF0000 -> 红色。
2、24位800*480bmp格式图片。 800*480 -> 代表这张图片由800*480个像素点 24位 -> 3个字节 (每一个像素点由3个字节组成) -> 三原色 每一个像素点都是BGR -> 蓝色,绿色,红色 总字节数:800*480*3
二、按照刚刚分析的结果,来写程序,看看效果如何。 1、打开图片 -> fopen() 2、将图片的数据读取到缓冲区中 -> fread() 3、打开lcd -> open() 4、将缓冲区的数据写入到lcd中 -> write() 5、关闭图片与lcd fclose() / close()
int main(int argc,char *argv[]) { FILE *fp; int n,lcd; char bmp_buf[800*480*3] = {0}; /*1. 打开图片 */ fp = fopen("./xx.bmp","r"); if(fp == NULL) printf("fopen error!\n"); /*2. 打开lcd设备 */ lcd = open("/dev/fb0",O_RDWR); if(lcd < 0) printf("open fb0 error!\n"); /*3. 将图片的数据读取到缓冲区中 */ n = fread(bmp_buf,800*480*3,1,fp); if(n!=1) printf("fread error!\n"); /* 4. 将缓冲区的数据写入到屏幕上 */ n = write(lcd,bmp_buf,sizeof(bmp_buf)); if(n!=sizeof(bmp_buf)) printf("write error!\n"); /* 5. 关闭文件 */ fclose(fp); close(lcd); return 0; }
结果: 1. lcd下半部分少了一截 -> 因为lcd是4个字节,图片是3个字节,所以一共少了4分之1 2. 形状不对 -> 像素点错位 颜色不对 -> 像素点没有存放到正确的位置
解决方案: 定位32位缓冲区,将bmp_buf经过处理,存放在32位缓冲区。
int main(int argc,char *argv[]) { FILE *fp; int n,lcd; int i,j; char bmp_buf[800*480*3] = {0}; char lcd_buf[800*480*4] = {0}; /*1. 打开图片 */ fp = fopen("./xx.bmp","r"); if(fp == NULL) printf("fopen error!\n"); /*2. 打开lcd设备 */ lcd = open("/dev/fb0",O_RDWR); if(lcd < 0) printf("open fb0 error!\n"); /*3. 将图片的数据读取到缓冲区中 */ n = fread(bmp_buf,800*480*3,1,fp); if(n!=1) printf("fread error!\n"); /*4. 将24位转32位 */ for(i=0,j=0;i<800*480*4;i+=4,j+=3) { lcd_buf[i+3] = bmp_buf[j]; lcd_buf[i+2] = bmp_buf[j+1]; lcd_buf[i+1] = bmp_buf[j+2]; lcd_buf[i] = 0; } /* 4. 将缓冲区的数据写入到屏幕上 */ n = write(lcd,lcd_buf,sizeof(lcd_buf)); if(n!=sizeof(lcd_buf)) printf("write error!\n"); /* 5. 关闭文件 */ fclose(fp); close(lcd); return 0; }
结果: 1. 大概的形状有了,但是颜色不对。 -> 像素点颜色没放对。 (蓝色是低位,lcd_buf[0]才是蓝色) 2. 上下颠倒。
解决方案:颜色位置不对。 for(i=0,j=0;i<800*480*4;i+=4,j+=3) { lcd_buf[i+3] = bmp_buf[j]; lcd_buf[i+2] = bmp_buf[j+1]; lcd_buf[i+1] = bmp_buf[j+2]; lcd_buf[i] = 0; } 修改成: for(i=0,j=0;i<800*480*4;i+=4,j+=3) { lcd_buf[i] = bmp_buf[j]; lcd_buf[i+1] = bmp_buf[j+1]; lcd_buf[i+2] = bmp_buf[j+2]; lcd_buf[i+3] = 0; }
结果: 1. 整张图片的右边的一些东西,显示在左边。 -> 头数据引起的。 2. 上下颠倒。
解决方案:先跳过54个字节,然后再读。
int main(int argc,char *argv[]) { FILE *fp; int n,lcd; int i,j; char bmp_buf[800*480*3] = {0}; char lcd_buf[800*480*4] = {0}; /*1. 打开图片 */ fp = fopen("./xx.bmp","r"); //默认在最开头 if(fp == NULL) printf("fopen error!\n"); /*2. 打开lcd设备 */ lcd = open("/dev/fb0",O_RDWR); if(lcd < 0) printf("open fb0 error!\n"); /*3. 先跳过54个头数据 */ fseek(fp,54,SEEK_SET); /*4. 将图片的数据读取到缓冲区中 */ n = fread(bmp_buf,800*480*3,1,fp); if(n!=1) printf("fread error!\n"); /*5. 将24位转32位 */ for(i=0,j=0;i<800*480*4;i+=4,j+=3) { lcd_buf[i] = bmp_buf[j]; lcd_buf[i+1] = bmp_buf[j+1]; lcd_buf[i+2] = bmp_buf[j+2]; lcd_buf[i+3] = 0; } /* 6. 将缓冲区的数据写入到屏幕上 */ n = write(lcd,lcd_buf,sizeof(lcd_buf)); if(n!=sizeof(lcd_buf)) printf("write error!\n"); /* 7. 关闭文件 */ fclose(fp); close(lcd); return 0; }
结果:上下颠倒。
解决方案:图片储存问题。 定义一个新的32位缓冲区,将旧的32位缓冲区的像素点重新排列好到新的32位缓冲区中, 然后再将新的缓冲区写入到lcd设备上。
作业1: 完成上下颠倒的任务。 作业2: 理解好同学的代码 D:\GZ2057\06 文件IO\04\homework\wxyp4.c 作业3: 好好复习标准IO的函数。 作业4: 完成昨晚剩余作业。 3、把项目中错误信息改成刷颜色。(选择来做,你就完成作业1,改成错误信息变成刷图) 4、究竟小孩退出登录时,要不要强制保存小孩的数据。 家长 -> 修改了小孩的年龄,密码之类 -> 需要保存到文件中。 -> 一定要做。