设计工作网站,大型网站开发 广州,头像logo图片在线制作免费,浙江vs广东联盟以下内容源于朱有鹏《物联网大讲堂》课程的学习整理#xff0c;如有侵权#xff0c;请告知删除。一、开始动手写代码
1、Makefile介绍
#xff08;1#xff09;这是一个通用的项目管理的Makefile体系#xff0c;自己写的#xff08;有子文件夹组织的#xff09;项目可以…以下内容源于朱有鹏《物联网大讲堂》课程的学习整理如有侵权请告知删除。一、开始动手写代码
1、Makefile介绍
1这是一个通用的项目管理的Makefile体系自己写的有子文件夹组织的项目可以直接套用这套Makefile体系。
2包含三类顶层Makefile、Makefile.build完全不需要改动、子文件夹下面的Makefile。子文件夹下的Makefile一般是类似下面的内容。3可以参考http://www.cnblogs.com/lidabo/p/4521123.html。2、使用SI建立工程二、framebuffer基本操作代码
显示图片需要framebuffer。三、图片显示原理和实践
1、图片显示原理
1概念1像素
2概念2点阵像素点构成的阵列
3分辨率物理分辨率物理屏幕像素点的真实个数显示分辨率可以小于等于物理分辨率通过抽样4清晰度与分辨率和像素间距有关主观概念像素间距相同时物理尺寸固定了则像素间距就固定了分辨率越大越清晰分辨率相同时像素间距越小越清晰。5bppRGB565、RGB888像素深度每个像素用多少bit数据表示。一般每个像素点使用32bit4个字节但一般是24位色高八位一般没用或者用着其他标识用00或者ff填充以达到内存对齐RGB888表示红用8位绿8位蓝8位。6颜色序RGB、BGR
2、图片点阵数据获取
1Image2LCD软件提取
2通过图片/视频文件直接代码方式提取四、图片数据提取和显示
1、Image2LCD提取图片数据
1软件下载http://www.cr173.com/soft/43222.html
2软件使用一般不要图像头数据只需要纯数据一般水平扫描一般选24位真彩色即RGB888选1024*600后点右边按钮更新输出图像调整中可以调整RGB。最后点击保存。2、图片显示编码与实践void fb_draw_picture(void)
{unsigned char* pdatagImage_1024600;unsigned int i,j,cnt;unsigned int*ppfb;for(i0;iHEIGHT;i){for(j0;jWIDTH;j){cnti*WIDTHj;cnt*3;*p((pdata[cnt0]0)|(pdata[cnt1]8)|(pdata[cnt2]16));//可以在这里修改达到正确的显示当RB相反时p;}}
}五、图片显示的高级话题
1、RGB顺序调整
1RGB顺序有三个地方都有影响第一个是fb驱动中的排布第二个是应用程序中的排布第三个是图像数据本身排布Image2LCD中调整RGB顺序2如果三个点中RGB顺序是一致的就会显示正常。如果三个设置不一致就可能会导致显示结果中R和B相反了
3实际写程序时一般不去分析这东西而是根据实际显示效果去调。如果反了就去调正应用程序中的RGB顺序就行了这样最简单。
2、显示函数的其他写法void fb_draw_picture2(void)
{unsigned char* pdatagImage_1024600;unsigned int x,y,cnt;for(y0;yHEIGHT;y){for(x0;xWIDTH;x){cnty*WIDTHx;*(pfbcnt)((pdata[cnt*30]16)|(pdata[cnt*31]8)|(pdata[cnt*32]0));//这里的像素矩阵和cnt有线性关系所以可以这样写}}
}六、任意分辨率大小图片显示
1图片比屏幕分辨率大这种情况下多出来的部分肯定是没法显示的。处理方法是直接在显示函数中把多余不能被显示的部分给丢掉。2图片大小比屏幕大小要小这种情况下图片只是填充屏幕中一部分剩余部分仍然保持原来的底色。在获取图片数据时大小和图片实际大小在这里是一致的。假如不一致呢void fb_draw_picture3(void)
{unsigned char* pdatagImage_500281;unsigned int x,y,cnt;unsigned int a0;for(y0;y281;y){for(x0;x500;x){cnty*WIDTHx;/*cnt始终都是framebuff像素点的编号*/*(pfbcnt)((pdata[a0]16)|(pdata[a1]8)|(pdata[a2]0));a3;/*由于空缺一部分像素点编号与像素点矩阵不存在倍数关系了此时应该三个三个地传送进来*/}}
}七、任意起点位置图片显示
1、小图片任意起点但整个图片显示没有超出屏幕范围内
算法1void fb_draw_picture4(unsigned int x0,unsigned int y0)
{unsigned char* pdatagImage_500281;unsigned int x,y,cnt;unsigned int cnt1,cnt2;for(yy0;y281y0;y){for(xx0;x500x0;x){cnt1y*WIDTHx;/*cnt始终都是fb 缓冲区整体中的像素点的编号*/cnt2500*(y-y0)(x-x0);*(pfbcnt1)((pdata[cnt2*30]16)|(pdata[cnt2*31]8)|(pdata[cnt2*32]0));/*左值考虑当前像素点在fb中的偏移量*//*右值考虑当前像素点在图像数据数组的下标这里是三个为一个元素的数组的下标因此上面会*3*/}}
}算法2因为每循环一次32、起点导致图片超出屏幕外
1现象左右超出去会在相反方向补全这是内部for循环可能超过1024的界定但没有超出fb的大小造成的。上下超出去则会消失因为双缓冲进到了另一帧。如果没有双缓冲则会内存溢出。2修改代码使得超出部分不再显示。
法一void fb_draw_picture5(unsigned int x0,unsigned int y0)
{unsigned char* pdatagImage_500281;unsigned int x,y,cnt;unsigned int a0;for(yy0;y281y0;y){if(yHEIGHT)//y方向超出{a3;break;//最后一行已经显示了剩下的不用考虑了}for(xx0;x500x0;x){if(xWIDTH)//x方向超出了{a3;continue;}cnty*WIDTHx;/*cnt始终都是像素点的编号*/*(pfbcnt)((pdata[a0]16)|(pdata[a1]8)|(pdata[a2]0));a3;/*因此像素点矩阵也应该三个三个地传送进来*/}}
}法二void fb_draw_picture4(unsigned int x0,unsigned int y0)
{unsigned char* pdatagImage_500281;unsigned int x,y,cnt;unsigned int cnt1,cnt2;for(yy0;y281y0;y){for(xx0;x500x0;x){if(xWIDTH)//x方向超出了{///a3;注意这里被诠释了continue;}cnt1y*WIDTHx;/*cnt始终都是fb 缓冲区整体中的像素点的编号*/cnt2500*(y-y0)(x-x0);*(pfbcnt1)((pdata[cnt2*30]16)|(pdata[cnt2*31]8)|(pdata[cnt2*32]0));/*左值考虑当前像素点在fb中的偏移量*//*右值考虑当前像素点在图像数据数组的下标*/}}
}八、BMP图片的显示
1、图片文件的本质
1图片文件是二进制文件。文件分两种即二进制文件、文本文件2不同格式的图片文件的差别。图片被压缩与否的区别。3BMP图片的基本特征未被压缩的元素位图格式bit map。2、BMP图片详解
1如何识别BMP文件每种图片格式都有定义好的一种识别方法BMP图片特征是以0x424D开头2BMP文件组成头信息有效信息3、BMP文件头信息、图片有效数据区
见博客https://www.2cto.com/kf/201310/252434.html
1文件大小
2有效数据开始的位置3信息头的大小40个字节
4分辨率524位真彩色6……
4、写代码解析BMP图片
第一步打开BMP图片
第二步判断图片格式是否真是BMP
第三步解析头信息得到该BMP图片的详细信息
第四步根据第三步得到的信息去合适位置提取真正的有效图片信息
第五步将得到的有效数据丢到fb中去显示
这样实际比较繁琐使用结构体比较好//path是bmp图片的pathname
//该函数解析path图片并将图片数据丢到bmp_buf中
//返回值错误时返回-1正确返回0
int bmp_analyze(unsigned char *path)
{int fd-1;unsigned char buf[54]{0};ssize_t ret0;//打开bmp文件fdopen(path,O_RDONLY);if(fd0){fprintf(stderr,open %s error.\n,path);return -1;}//读取文件头信息retread(fd,buf,54);if(ret!54){fprintf(stderr,read file header error.\n);return -1;}//解析头//判断是否BMP图片if(buf[0]!B||buf[1]!M){fprintf(stderr,file %s is not a bmp picture.\n,path);return -1;}printf(file %s is a bmp picture.\n,path);printf(width is %d\n,*((unsigned int*)(buf0x12)));printf(hith is %d\n,*((unsigned int*)(buf0x16)));//成功则说明小端模式close(fd);return 0;}
5、用结构体方式解析BMP文件头
6、用结构体方式解析BMP信息头#ifndef __BMP_H__
#define __BMP_H__typedef struct
{unsigned char bfType[2];//文件类?unsigned long bfSize; //位图大小 unsigned short bfReserved1; //位0 unsigned short bfReserved2; //位0 unsigned long bfOffBits;//到数据偏移量
}__attribute__((packed))BitMapFileHeader;//使编译器不优化其大小为14字节 //信息头结构体
typedef struct
{ unsigned long biSize;// BitMapFileHeader 字节数long biWidth;//位图宽度 long biHeight;//位图高度正位正向反之为倒图 unsigned short biPlanes;//为目标设备说明位面数其值将总是被设为1unsigned short biBitCount;//说明比特数/象素为1、4、8、16、24、或32。 unsigned long biCompression;//图象数据压缩的类型没有压缩的类型BI_RGB unsigned long biSizeImage;//说明图象的大小以字节为单位 long biXPelsPerMeter;//说明水平分辨率 long biYPelsPerMeter;//说明垂直分辨率 unsigned long biClrUsed;//说明位图实际使用的彩色表中的颜色索引数unsigned long biClrImportant;//对图象显示有重要影响的索引数0都重要。
} __attribute__((packed)) BitMapInfoHeader; #endifvoid fb_draw(const unsigned char* ppic)
{unsigned char* pdatappic;unsigned int x,y;unsigned int a0;unsigned int cnt0;a281*500*3-3;for(y0;y281;y){for(x0;x500;x){cnty*WIDTHx;*(pfbcnt)((pdata[a0]16)|(pdata[a1]8)|(pdata[a2]0));a-3;}//a表示每个像素的三个字节数据的首字节编号}
}//path是bmp图片的pathname
//该函数解析path图片并将图片数据丢到bmp_buf中
//返回值错误时返回-1正确返回0
int bmp_analyze(unsigned char *path)
{int fd-1;BitMapFileHeader fheader ;BitMapInfoHeader info;ssize_t ret0;int i;unsigned long len;//打开bmp文件fdopen(path,O_RDONLY);if(fd0){fprintf(stderr,open %s error.\n,path);return -1;}ret read(fd,fheader,sizeof(fheader));printf(bfsize %d.\n,fheader.bfSize);//位图大小printf(boffsize %d.\n,fheader.bfOffBits);//有效信息偏移量#if 0for( i0;isizeof(fheader);i){printf(%x ,*((unsigned char *)fheaderi));}printf(\n);
#endifret read(fd,info,sizeof(info));/*会沿着继续读下去*/printf(picture resolution : %d * %d.\n,info.biHeight,info.biWidth);printf(picture bpp : %d \n,info.biBitCount);//读取图片有效信息//先把文件指针移动到有效信息的偏移量处(lseek函数)//然后读出info.biHeight*info.biWidth*info.biBitCount/8个字节lseek(fd,fheader.bfOffBits,SEEK_SET);//从文件开始的位置开始leninfo.biHeight*info.biWidth*info.biBitCount /8;printf(len put to buff :%ld.\n,len);read(fd,bmp_buf,len);//把内容丢到fb中去显示fb_draw(bmp_buf);/*数据和使用image2lcd获取的不一样*这里会旋转180度颠倒*即第一个像素放到最后一个像素点像素依次类推了*/close(fd);return 0;
}注意使用结构体来解析图片数据时和使用image2lcd不一样。这里会旋转180度颠倒即第一个像素放到最后一个像素点像素依次类推了。因此在fb_draw()函数中需要将最后一个像素点数据放在第一个像素处显示以此类推。---------------以上代码写得不规整要进行规整--------------------
九、及时规整
1、再次强调规范问题
1函数、变量起名字要合法合理小写函数2要写注释第一步第二步……可以先写注释再写代码3函数长短要合适
4多文件组织每个东西丢到合理的位置
2、为什么要规整项目
1完全自由写项目时不可能一步到位只能先重内容和功能后补条理和规范
2规整的过程也是一个梳理逻辑和分析架构的过程。
3、对本项目进行规整
1去掉测试显示时头文件形式提供的图片显示相关的东西即去除fb_draw_picture_n()测试函数因为我们的最终目的是解析bmp格式图片已经实现了因此要删除之前的测试函数4、一些重构代码的技巧
1用#if 0 #endif来屏幕不需要的代码不要用/* */
2暂时不要的代码先不要删除而是屏幕掉5、添加DEBUG宏以控制调试信息输出
debug宏添加好后要使能输出可以有2种方式
第一种在debug宏定义之前定义DEBUG宏。见http://blog.csdn.net/oqqhutu12345678/article/details/78873195第二种在编译参数中添加-DDEBUG编译选项。在makefile中添加6、图片信息用结构体来封装传递//封装图片各种信息
typedef struct pic_info
{char* pathname;//路径和文件名字unsigned int width;unsigned int height;unsigned int bpp;unsigned char *pData;//指向图片有效数据存储的buff}pic_info;
从而需要修改相关代码。十、jpg图片的显示原理分析
1、认识jpg图片
1属于二进制文件。
2有其固定的识别特征http://www.cnblogs.com/Wendy_Yu/archive/2011/12/27/2303118.html
3是经过压缩的图片格式。
2、jpg图片如何显示
1jpg图片中的二进制数并不对应像素数据。
2LCD显示器的接口仍然是framebuffer。
3要显示jpg图片必须先解码jpg得到相应的位图数据。
3、如何解码jpg图片
1图片编码和解码对应着压缩和解压缩过程
2编码和解码其实就是一些数学运算压缩度、算法复杂度、时间、清晰度
3软件编解码和硬件编解码需要频繁进行编解码的话一般使用硬件编解码。4不同的图片格式其实就是编解码的算法不同结果是图片特征不同
5编程实战使用开源编解码库十一、libjpeg介绍及开源库的使用方法
1、libjpeg介绍
1基于linux的开源软件
2C语言编写gcc、使用Makefile管理
3提供JPEG图片的编解码算法实现
2、libjpeg版本及下载资源
1经典版本v6bhttps://sourceforge.net/projects/libjpeg/files/libjpeg/6b/
2最新版本v9bhttp://www.ijg.org/
3、开源库的使用方法
1移植源码下载、解压、配置、修改Makefile、编译或交叉编译移植的目的是由源码得到三个东西动态库.so静态库.a头文件.h。2部署部署动态库so、部署静态库.a和头文件.h动态库是程序在运行时才需要的编译程序时不需要。静态库是静态连接时才需要动态链接时不需要。头文件.h是在编译程序时使用的运行时不需要的。静态库和头文件是在编译链接过程中需要的因此要把静态库.a文件和头文件.h文件放到ubuntu的文件系统中。动态库是在运行时需要的所以动态库so文件要放到开发板的文件系统中放的过程就叫部署。3注意三个编译链接选项-I -l小L -L
举例如-I-I是编译选项准确的是说是makefile预处理选项CFLAGS或者CPPFLAGS中指定用来指定预处理时查找头文件的范围的。-l小写L是链接选项LDFLAGS中指定用来指定链接额外的库的名字譬如我们用到了数学函数就用-lm链接器就会去链接libm.so那么我们使用了libjpeg对应的库名字就叫libjpeg.so就需要用-ljpeg选项去链接。-L是链接选项LDFLAGS中指定用来指定链接器到哪个路径下面去找动态链接库。总结-l小写L是告诉链接器要链接的动态库的名字而-L是告诉链接器要链接的动态库的路径。十二、libjpeg的移植实战
1、移植
1源码下载、解压至/tmp/decodeporting目录下。
2编译前的配置分析configure文件的usage、借鉴前辈的设置得到应该执行下面命令./configure --prefix/opt/libcode --exec-prefix/opt/libcode --enable-shared --enable-static-buildi386 -hostarm 指定编译结果放置的目录如果没有则需要先建立相应的目录配置生成了makefile文件通过查看知道需要在/opt/libcode中创建include、bin、lib目录。3Makefile检查主要查看交叉编译设置是否正确CCgcc 改为 CCarm-linux-gcc //编译器如果不改只能在ubuntu使用不能在开发板使用。ARar rc 改为 ARarm-linux-ar rcAR2ranlib 改为 AR2arm-linux-ranlib
4编译执行make命令。
5安装执行make install-lib安装就是将编译生成的库文件、头文件、可执行文件分别装载到--prefix --exec-prefix所指定的那些目录中去。2、部署
前面只是完成移植相关文件都在ubuntu上。我们要把动态链接库(.so文件)放到开发板的根文件系统中/root/rootfs/可以考虑三者之一:第一个/lib第二个/usr/lib前两个在程序运行时可以自动找到。后面任意目录时需要在程序中指定第三个任意指定目录十三、使用libjpeg解码显示jpg图片
1、如何使用一个新的库
(1)思路一网络上找别人使用过后写的文档、博客等作为参考。
(2)思路二看库源码自带的文档说明文档和示例代码。我们从思路二出发。
2、libjpeg说明文档和示例代码
(1)说明文档README和libjpeg.doc
(2)示例代码example.c
3、结合说明文档来实践4、解读example.c和移植5、代码问题
(1)测试代码先试图读取jpg图片头信息。
(2)问题排除
编译时问题主要就是头文件包含除了在代码中包含头文件外还要注意指明头文件的路径。因为尽管包含了头文件但只会在当前的目录和path指定的路径中寻找。我们应该在总Makefile中指定。注意-I、-l、-L三个编译链接选项的使用6、部署动态库以使程序运行起来(1)一般放到开发板根文件系统/lib或者/usr/lib下
这样不需要给系统指定库路径就能自动找到。强调一下是开发板根文件系统下的路径千万不要弄成了ubuntu的根文件系统下的目录。
(2)放到自定义的第三方的目录
将该自定义第三方目录导出到环境变量LD_LIBRARY_PATH下即可。可以使用echo $LD_LIBRARY_PATH查看当前的路径环境变量包含哪些路径。可以把上述操作写进到run.sh文件中省得每次都要这样操作。7、测试读取头信息十四、解决解码显示中的问题
1、问题分析及解决记录
1根据LCD错误的显示状态分析有可能是显示函数fb_draw中的图片宽高数据有误于是在fb_draw函数中添加debug打印出宽和高来。结果发现是对的。
2显示函数中的图片宽高和fb宽高都是对的结果显示时还是只有一溜其余位置黑屏可能的一个原因就是显示数据本身不对很多都是0。如何验证只要把显示数据打印出来看一看就知道了。结果发现打印出的待显示数据果然是很多0说明给显示函数的待显示数据就是错的。3这些待显示数据为什么会错第一种可能性就是libjpeg解码出来的数据就是错的第二种可能性是解码一行出来暂存到buffer的时候或者memcpy从暂存的buffer拿出来给pData指向的空间的时候给搞错了。相对来说第二种很好验证而第一种不好验证。只需要在jpeg_read_scanlines函数后面直接打印显示解码出来的一行数据就可以知道是不是第二种情况。结果打印出来好多0说明是第一种情况。4截至目前已经锁定问题就是jpeg_read_scanlines解码出来的数据本身就不对。
5可能的问题有可能是libjpeg本身就有问题有可能我们对libjpeg的部署不对导致他工作不对有可能我们写的代码不对也就是说我们没用正确的方法来使用libjpeg。6没有思路怎么办
去网上找一些别人写的libjpeg解码显示图片的示例代码多看几个对着和我们的关键部位对比寻找思路。如果在网上找不到相关资料这时候就只有硬着头皮去看源码了。譬如去libjpeg的源码中查看jpeg_read_scanlines、cinfo.mem-alloc_sarray等。
7解决了buffer申请导致的问题之后我们再来解决2个遗留的问题一个就是RGB顺序问题另一个是图像转了180度的问题。8添加了fb_draw2函数并且调用后2个遗留问题彻底解决。至此jpg图片显示完美实现。
2、结束jpg图片部分
1加上jpg图片格式识别判断开头和结尾的特征字节。
2对外封装好用的jpg图片显示函数
3对外封装好用的bmp图片显示函数十五、解码显示png图片
1、思路分析
1png更像是jpg而不像是bmp
2png和jpg都是压缩格式的图片都是二进制文件不同之处是压缩和解压缩的算法不同。
3通过libjpeg来编解码jpg图片那么同样有一个libpng用来编解码png图片。
4工作思路和顺序找到并移植并部署libpng然后查readme和其他文档示例代码等来使用libpng提供的API来对png图片进行解码并将解码出来的数据丢到framebuffer中去显示。2、libpng移植
1下载源码包
2解压、配置、修改Makefile、编译、部署。注意实际路径。./configure --hostarm-linux --enable-shared --enable-static --prefix/opt/libdecode3配置出错报错信息configure: error: zlib not installed分析问题是因为libpng依赖于zlib库所以要先移植zlib库才可以。4移植了zlib后再过来配置还是报错原因是因为没有导出相关环境变量所以libpng在配置的时候找不到刚才移植的zlib库的库文件和头文件。
5解决方案就是使用epport临时性的导出在scrt中输入
# export LDFLAGS-L/opt/libdecode/lib
# export CFLAGS-I/opt/libdecode/include
# export CPPFLAGS-I/opt/libdecode/include
6导出后再次配置就过了然后编译和安装
7make make install
3、zlib移植
1下载http://www.zlib.net/并解压
2配置export CCarm-linux-gcc
./configure -shared --prefix/opt/libdecode
3make make install
4make install后/opt/libdecode目录下的lib和include目录下就有了zlib的静态库动态库和头文件了然后再回去继续libpng的移植。4、参考源码包自带的资料开始编程
1readme
2libpng-manual.txt
3example.c 和 pngtest.c十六、图片文件的管理和检索1、图片文件的管理
1在物理磁盘存储层次上用一个文件夹来管理
2在程序中用数据结构来管理。
用数组管理用链表管理
4编程实战细节见代码下面是关键点
a、新建一个文件夹记得要在makefile中添加新建的文件夹路径以及在新建文件夹中新建makefile来管理文件。
b、文件夹的打开操作、读取操作2、图片信息的自动检索
1读取文件类型
2普通文件和文件夹分类处理
3普通文件区分将其中的图片按格式存储到图片管理数组/链表中typedef enum image_type
{IMAGE_TYPE_BMP,IMAGE_TYPE_JPG,IMAGE_TYPE_UNKNOWN,
}image_type_e;typedef struct image_info
{char pathname[PATHNAME_LEN];image_type_e type;
}image_info_t;int scan_image2(const char *path)
{// 在本函数中递归检索path文件夹将其中所有图片填充到iamges数组中去DIR *dir;struct dirent *ptr;char base[1000];struct stat sta;if ((dir opendir(path)) NULL){perror(Open dir error...);exit(1);}// readdir函数每调用一次就会返回opendir打开的basepath目录下的一个文件直到// basepath目录下所有文件都被读完之后就会返回NULLwhile ((ptr readdir(dir)) ! NULL){if(strcmp(ptr-d_name, .)0 || strcmp(ptr-d_name, ..)0) ///current dir OR parrent dircontinue;// 用lstat来读取文件属性并判断文件类型memset(base,\0,sizeof(base));//strcpy(base,path);strcat(base,/);strcat(base,ptr-d_name);lstat(base, sta);if (S_ISREG(sta.st_mode)){//printf(regular file.\n);//printf(d_name:%s/%s\n, path, ptr-d_name);// 如果是普通文件就要在这里进行处理:// 处理思路就是 先判定是否属于已知的某种图片格式如果是则放到images数组中// 如果都不属于则不理他if (!is_bmp(base)){strcpy(images[image_index].pathname, base);images[image_index].type IMAGE_TYPE_BMP;}if (!is_jpg(base)){strcpy(images[image_index].pathname, base);images[image_index].type IMAGE_TYPE_JPG;}image_index;}if (S_ISDIR(sta.st_mode)){//printf(directory.\n);//printf(d_name:%s/%s\n, path, ptr-d_name);scan_image2(base);}}
}void show_images(void)
{int i;for (i0; iimage_index; i){switch (images[i].type){case IMAGE_TYPE_BMP:display_bmp(images[i].pathname); break;case IMAGE_TYPE_JPG:display_jpg(images[i].pathname); break;default:break;}sleep(2);}
}十七、添加触摸翻页功能
1、读取触摸坐标数据开发板上的触摸屏是/dev/input/event2我这里是event22、使用触摸坐标判断并执行翻页操作
1执行./run.sh后会阻塞如果点击触摸屏会在scrt中显示测试的内容。code 0表示x坐标value为x的值code 1表示y坐标value为y的值。2在不同区域点一下有不同的效果。十八、总结与回顾
1、bug解决
2、项目总结
1项目描述软硬件平台等
2重点和难点
3、项目展望与扩展功能
1划屏翻页
2图片放大与缩小显示
3动画
4开机画面
5背景音乐