一、BMP图的实现

练习1: 再实现一张BMP图

 //打开lcdint lcd = open("/dev/fb0",O_RDWR);if(lcd < 0){perror("open error!\n");return -1;}//lcd映射//指针指向一个像素点int *p = mmap(NULL,800*480*4,PROT_READ|PROT_WRITE,MAP_SHARED,lcd,0);if(p == NULL){perror("mmap fail!\n");return -1;}//打开bmp图片int lcd_bmp = open("1.bmp",O_RDWR);if(lcd_bmp < 0){printf("open bmp fail!\n");return -1;}//去除掉头54个字节lseek(lcd_bmp,54,SEEK_SET);//存储bmp图片的buffer:800*480*3char buf[800*480*3] = {0};//读bmp图片read(lcd_bmp,buf,800*480*3);//将buf数据通过指针p填充到LCD中// int i;// for(i=0;i<800*480;i++)// {// *(p+i) = buf[3*i] |buf[3*i+1]<<8 |buf[3*i+2]<<16;// }//将buf数据通过指针p填充到LCD中int x;//x表示横轴int y;//y表示纵轴for(y=0;y<480;y++){for(x=0;x<800;x++){/*将buf[]里面的数据由BGR换成RGB将3个字节封装成4个字节*/*(p+((479-y)*800+x)) = (buf[3*(y*800+x)+0]) | (buf[3*(y*800+x)+1]<<8) | (buf[3*(y*800+x)+2]<<16);/*0 = buf[0] | buf[1]<<8 | buf[2]<<161 = buf[3] | buf[4]<<8 | buf[5]<<162 = buf[6] | buf[7]<<8 | buf[8]<<16800 = buf[800*3] | buf[800*3+1]<<8 | buf[800*3+2]<<16*/}}//lcd映射释放munmap(p,800*480*4);//关闭lcd\bmpclose(lcd);close(lcd_bmp);

练习2: 实现3张照片的轮流播放 sleep(1);//延时1秒 usleep(1); //延时微秒 推展:能否将你实现bmp照片的代码封装成一个函数

int show_pic(int *p,char *bmp_path){//打开bmp图片int bmp = open(bmp_path,O_RDWR);if(bmp < 0){printf("open bmp fail!\n");return -1;}//去除掉头54个字节lseek(bmp,54,SEEK_SET);//存储bmp图片的buffer:800*480*3char buf[800*480*3] = {0};int ret1 = read(bmp,buf,800*480*3);sleep(1);//读bmp图片//将buf数据通过指针p填充到LCD中int x;//x表示横轴int y;//y表示纵轴for(y=0;y<480;y++){for(x=0;x<800;x++){/*将buf[]里面的数据由BGR换成RGB将3个字节封装成4个字节*/*(p+((479-y)*800+x)) = (buf[3*(y*800+x)+0]) | (buf[3*(y*800+x)+1]<<8) | (buf[3*(y*800+x)+2]<<16);/*0 = buf[0] | buf[1]<<8 | buf[2]<<161 = buf[3] | buf[4]<<8 | buf[5]<<162 = buf[6] | buf[7]<<8 | buf[8]<<16800 = buf[800*3] | buf[800*3+1]<<8 | buf[800*3+2]<<16*/}}close(bmp);return 0;}int main(int argc,char *argv[]){//打开lcdint lcd = open("/dev/fb0",O_RDWR);if(lcd < 0){perror("open lcd error!\n");return -1;}//lcd映射//指针指向一个像素点int *p = mmap(NULL,800*480*4,PROT_READ|PROT_WRITE,MAP_SHARED,lcd,0);if(p == NULL){perror("mmap fail!\n");return -1;}//指针数组存储字符串char *bmp_path[] = {"1.bmp","zhao.bmp","guo.bmp","curry.bmp"};int n = 4;int i =0 ;while(1){for(i=0;i<4;i++){show_pic(p,bmp_path[i]);sleep(1);}}//lcd映射释放munmap(p,800*480*4);//关闭lcd\bmpclose(lcd);return 0;}

命名规则: 1.windows里面的命名 以大写字母开头来区分与单词之间 ShowBmp

2. linux里面的命名 以”_”来区分与单词之间 show_bmp

3.驼峰命名法 1)小驼峰: int myStudentCount; 变量myStudentCount第一个单词是全部小写,后面的单词首字母大写。

2)大驼峰 public class DataBaseUser 相比小驼峰法,大驼峰法(即帕斯卡命名法)把第一个单词的首字母也大写了

4.具体用什么方法来命名 由老板来决定

二、计算bmp图片的宽度和高度 通过bmp图片的头54个字节来计算bmp图片的高度和宽度

那如果是一张800*480的图片,那么他的 int hight = 480 int width = 800 lseek(fd_bmp,18,SEEK_SET); //光标是在18位置 read(fd_bmp,&width,4); //光标是在22位置 read(fd_bmp,&hight,4); printf(“width=%d hight=%d\n”,width,hight);

 int bmp_fd = open(argv[1], O_RDWR);if (bmp_fd == -1) {printf("打开失败\n");return -1;}char header[54]; //储存头文件数据read(bmp_fd, header, 54); //读取头文件数据int w, h; //定义宽、高变量lseek(bmp_fd,18,SEEK_SET);read(bmp_fd,&w,4);read(bmp_fd,&h,4);printf("h:%d w:%d\n",h,w);close(bmp_fd);

二、如何使用jpg图片

bmp图片:优点:读取数据方便,实现一张800*480代码比较简单;缺点:图片太大,要增加硬件成本 jpg图片:优点:图片小便于存储;缺点:要解压图片代码比较复杂

1.如何使用第三方库来解压jpg图片 1)如何使用第三方库(别人开发的库文件–外库)—–>移植 三大神步骤 配置 ./configure 编译 make安装 make install

2)如何来移植一个jpeg库 移植成功之后开发板的操作: [root@GEC6818 /IOT/bling]#chmod 777 main [root@GEC6818 /IOT/bling]# [root@GEC6818 /IOT/bling]#./main (没移植库前会出现如下错误) ./main: error while loading shared libraries: libjpeg.so.9: cannot open shared object file: No such file or directory [root@GEC6818 /IOT/bling]#chmod 777 libjpeg.so.9(一定要修改库的权限)[root@GEC6818 /IOT/bling]# [root@GEC6818 /IOT/bling]#cp libjpeg.so.9 /lib/

三、安装小工具 如何开火车和养猫 sudo apt-get install sl //火车 sl –help sudo apt-get install oneko //hellokitty 猫 oneko –help oneko -bg red 给猫一个红色 说明: (前提需要ubuntu联外网) sudo apt-get update //更新软件源

作业1: 实现4张照片的轮流播放 2张bmp(800*480) 2张jpg(400*240)这两张放同一平面上

lcdjpg.c

#include #include #include #include #include #include #include #include "lcdjpg.h"#include "jpeglib.h"#include static char g_color_buf[FB_SIZE]={0};static int g_fb_fd;static int *g_pfb_memory;/* video_chat.c ?-?D?-??ê?μ?×?±ê */volatile int g_jpg_in_jpg_x;volatile int g_jpg_in_jpg_y;unsigned long file_size_get(const char *pfile_path){unsigned long filesize = -1;struct stat statbuff;if(stat(pfile_path, &statbuff) < 0){return filesize;}else{filesize = statbuff.st_size;}return filesize;}//LCD?-μ?void lcd_draw_point(unsigned int x,unsigned int y, unsigned int color){*(g_pfb_memory+y*800+x)=color;}int lcd_draw_jpg(unsigned int x,unsigned int y,const char *pjpg_path,char *pjpg_buf,unsigned int jpg_buf_size,unsigned int jpg_half){//3?ê??ˉLCDg_fb_fd = open("/dev/fb0", O_RDWR);if(g_fb_fd<0){printf("open lcd error\n");return -1;}g_pfb_memory = (int *)mmap( NULL, //ó3é???μ??aê?μ??·£?éè???aNULLê±±íê?óé?μí3???¨ó3é???μ??eê?μ??·FB_SIZE, //ó3é???μ?3¤?èPROT_READ|PROT_WRITE, //?úèY?éò?±??áè?oíD′è?MAP_SHARED, //12?í?ú′?g_fb_fd, //óDD§μ????t?èê?′ê0 //±?ó3é????ó?úèYμ??eμ?);/*?¨ò??a?????ó£?′í?ó′|àí???ó*/struct jpeg_decompress_struct cinfo;struct jpeg_error_mgr jerr;char *pcolor_buf = g_color_buf;char *pjpg;unsigned int i=0;unsigned int color =0;unsigned int count =0;unsigned int x_s = x;unsigned int x_e ;unsigned int y_e ;int jpg_fd;unsigned int jpg_size;unsigned int jpg_width;unsigned int jpg_height;if(pjpg_path!=NULL){/* éê??jpg×ê?′£?è¨?T?é?á?éD′ */jpg_fd=open(pjpg_path,O_RDWR);if(jpg_fd == -1){printf("open %s error\n",pjpg_path);return -1;}/* ??è?jpg???tμ?′óD? */jpg_size=file_size_get(pjpg_path);/* ?ajpg???téê???ú′????? */pjpg = malloc(jpg_size);/* ?áè?jpg???t?ùóD?úèYμ??ú′? */read(jpg_fd,pjpg,jpg_size);}else{jpg_size = jpg_buf_size;pjpg = pjpg_buf;}/*×¢2á3?′í′|àí*/cinfo.err = jpeg_std_error(&jerr);/*′′?¨?a??*/jpeg_create_decompress(&cinfo);/*?±?ó?a???ú′?êy?Y*/jpeg_mem_src(&cinfo,pjpg,jpg_size);/*?á???tí·*/jpeg_read_header(&cinfo, TRUE);/*?aê??a??*/jpeg_start_decompress(&cinfo);if(jpg_half){x_e = x_s+(cinfo.output_width/2);y_e = y +(cinfo.output_height/2);/*?á?a??êy?Y*/while(cinfo.output_scanline < cinfo.output_height){pcolor_buf = g_color_buf;/* ?áè?jpgò?DDμ?rgb?μ */jpeg_read_scanlines(&cinfo,(JSAMPARRAY)&pcolor_buf,1);/* ?ù?áè?jpgò?DDμ?rgb?μ */jpeg_read_scanlines(&cinfo,(JSAMPARRAY)&pcolor_buf,1);for(i=0; i<(cinfo.output_width/2); i++){/* ??è?rgb?μ */color = *(pcolor_buf+2);color = color | *(pcolor_buf+1)<<8;color = color | *(pcolor_buf)<<16;/* ??ê?????μ? */lcd_draw_point(x,y,color);pcolor_buf +=6;x++;}/* ??DD */y++;x = x_s;}}else{x_e = x_s+cinfo.output_width;y_e = y +cinfo.output_height;/*?á?a??êy?Y*/while(cinfo.output_scanline < cinfo.output_height ){pcolor_buf = g_color_buf;/* ?áè?jpgò?DDμ?rgb?μ */jpeg_read_scanlines(&cinfo,(JSAMPARRAY)&pcolor_buf,1);for(i=0; i<cinfo.output_width; i++){/* ??è?rgb?μ */color = *(pcolor_buf+2);color = color | *(pcolor_buf+1)<<8;color = color | *(pcolor_buf)<<16;/* ??ê?????μ? */lcd_draw_point(x,y,color);pcolor_buf +=3;x++;}/* ??DD */y++;x = x_s;}}/*?a??íê3é*/jpeg_finish_decompress(&cinfo);jpeg_destroy_decompress(&cinfo);if(pjpg_path!=NULL){/* 1?±?jpg???t */close(jpg_fd);/* êí·?jpg???t?ú′????? */free(pjpg);}//LCD1?±?/* è????ú′?ó3é? */munmap(g_pfb_memory, FB_SIZE);/* 1?±?LCDéè±? */close(g_fb_fd);return 0;}

lcdjpg.h

#ifndef __LCDJPG_H__#define __LCDJPG_H__#define LCD_WIDTH 800#define LCD_HEIGHT 480#define FB_SIZE (LCD_WIDTH * LCD_HEIGHT * 4)//my_head.h#include #include #include #include #include #include #include #include #include #include int show_pic(int *p,char *bmp_path);/* video_chat.c 画中画显示的坐标 */extern volatile int g_jpg_in_jpg_x;extern volatile int g_jpg_in_jpg_y;void lcd_draw_point(unsigned int x,unsigned int y, unsigned int color);int lcd_draw_jpg(unsigned int x,unsigned int y,const char *pjpg_path,char *pjpg_buf,unsigned int jpg_buf_size,unsigned int jpg_half);#endif

main.c

#include #include "lcdjpg.h"/*参数说明:0:x坐标0:y坐标./2.jpg:图片的名字NULL:pjpg_buf0:jpg_buf_size0:jpg_half编译:arm-linux-gcc *.c -o main -I./libjpeg -L./libjpeg -ljpeg*/int main(void){//打开lcdint lcd = open("/dev/fb0",O_RDWR);if(lcd < 0){perror("open lcd error!\n");return -1;}//lcd映射//指针指向一个像素点int *p = mmap(NULL,800*480*4,PROT_READ|PROT_WRITE,MAP_SHARED,lcd,0);if(p == NULL){perror("mmap fail!\n");return -1;}//指针数组存储字符串char *bmp_path[] = {"zhao.bmp","guo.bmp"};int n = 2;int i =0 ;while(1){for(i=0;i<2;i++){show_pic(p,bmp_path[i]);sleep(1);lcd_draw_jpg(0,0,"./curry.jpg",NULL,0,0);sleep(1);lcd_draw_jpg(400,0,"./tom.jpg",NULL,0,0);sleep(1);lcd_draw_jpg(0,240,"./james.jpg",NULL,0,0);sleep(1);lcd_draw_jpg(400,240,"./jr.jpg",NULL,0,0);sleep(1);}}//lcd映射释放munmap(p,800*480*4);//关闭lcd\bmpclose(lcd);return 0;}

show_pic_fun.c

#include "my_head.h"int show_pic(int *p,char *bmp_path){//打开bmp图片int bmp = open(bmp_path,O_RDWR);if(bmp < 0){printf("open bmp fail!\n");return -1;}//去除掉头54个字节lseek(bmp,54,SEEK_SET);//存储bmp图片的buffer:800*480*3char buf[800*480*3] = {0};int ret1 = read(bmp,buf,800*480*3);sleep(1);//读bmp图片//将buf数据通过指针p填充到LCD中int x;//x表示横轴int y;//y表示纵轴for(y=0;y<480;y++){for(x=0;x<800;x++){/*将buf[]里面的数据由BGR换成RGB将3个字节封装成4个字节*/*(p+((479-y)*800+x)) = (buf[3*(y*800+x)+0]) | (buf[3*(y*800+x)+1]<<8) | (buf[3*(y*800+x)+2]<<16);/*0 = buf[0] | buf[1]<<8 | buf[2]<<161 = buf[3] | buf[4]<<8 | buf[5]<<162 = buf[6] | buf[7]<<8 | buf[8]<<16800 = buf[800*3] | buf[800*3+1]<<8 | buf[800*3+2]<<16*/}}close(bmp);return 0;}

编译: arm-linux-gcc *.c -o main -I./libjpeg -L./libjpeg -ljpeg

附加题:(前提条件小于800*480) 通过读取bmp图片的高度和宽度来实现任意一张任意大小的bmp图片

/*说明:图片的宽度一定要是4的倍数,如果不是4的倍数,需要做像素点补偿(专业)所以我们自己制作bmp图片,宽度要做成4的倍数图片的大小和你的偏移量合起来不能超过整个屏幕*/int show_bmp_size(int *p,char *bmp_path,int offset_x,int offset_y){//打开bmp图片int lcd_bmp = open(bmp_path,O_RDWR);//800*480的图片if(lcd_bmp < 0){printf("open bmp fail!\n");return -1;}int wide=0,hight=0;lseek(lcd_bmp,18,SEEK_SET);read(lcd_bmp,&wide,4);read(lcd_bmp,&hight,4);printf("hight:%d wideZ:%d\n",hight,wide);//去除掉头54个字节lseek(lcd_bmp,54,SEEK_SET);//存储bmp图片的buffer:800*480*3char buf[wide*hight*3];//读bmp图片read(lcd_bmp,buf,wide*hight*3);// int offset_x = 100;//图片x起始位置// int offset_y = 100;//图片y起始位置printf("offset_x:%d offset_y:%d\n",offset_x,offset_y);//将buf数据通过指针p填充到LCD中int x;//x表示横轴int y;//y表示纵轴for(y=0;y<hight;y++){for(x=0;x<wide;x++){/*屏幕的起始坐标值应该从偏移量开始offset_y+hight 是最后一行起始点的纵轴坐标offset_x是最后一行起始点横轴坐标*/*(p+(offset_y+hight-1-y)*800+offset_x+x) = (buf[3*(y*wide+x)+0])| (buf[3*(y*wide+x)+1]<<8)| (buf[3*(y*wide+x)+2]<<16);/*0 = buf[0] | buf[1]<<8 | buf[2]<<161 = buf[3] | buf[4]<<8 | buf[5]<<162 = buf[6] | buf[7]<<8 | buf[8]<<16800 = buf[800*3] | buf[800*3+1]<<8 | buf[800*3+2]<<16*/}}close(lcd_bmp);return 0;}int main(int argc,char *argv[]){if(argc !=4){printf("./a.out   ");return -1;}//打开lcdint lcd = open("/dev/fb0",O_RDWR);if(lcd < 0){perror("open error!\n");return -1;}//lcd映射//指针指向一个像素点int *p = mmap(NULL,800*480*4,PROT_READ|PROT_WRITE,MAP_SHARED,lcd,0);if(p == NULL){perror("mmap fail!\n");return -1;}//argv[1]照片名字//atoiargv[2]照片x轴起始位置//atoiargv[3]照片y轴起始位置show_bmp_size(p,argv[1],atoi(argv[2]),atoi(argv[3]));//lcd映射释放munmap(p,800*480*4);//关闭lcd\bmpclose(lcd);return 0;}