文章目录

  • 实验要求
  • 代码实现
    • lcd.h
    • lcd.c
    • touch.h
    • touch.c
    • main.c

实验要求

  1. 分别实现5个按钮:上一张下一张,随机播放,循环播放,停止循环播放
  2. 在屏幕里选择一块区域显示图片,该区域同时也可以使用滑动.

代码实现

lcd.h

#ifndef LCD_H
#define LCD_H/*函数声明*/
int *Init_LCD(int *fd);
void Uninit_LCD(int fd,int *plcd);
void Lcd_draw_point(int x,int y,int color,int *plcd);
void Lcd_draw_matrx(int x,int y,int h,int w,int color,int *plcd);
int Bmp_display(const char *bmp_file,int x0,int y0,int *plcd);#endif

lcd.c

/*头文件*/
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <sys/mman.h>
#include <stdlib.h>/*宏定义*/
#define FILE_PATH "/dev/fb0"/*Init_LCD:初始化显示屏参数为空返回值 int*成功 返回映射区域的首地址失败 返回NULL
*/
int *Init_LCD(int *fd)
{//1.打开帧缓冲*fd = open("/dev/fb0",O_RDWR);if(-1 == *fd){perror("open fail");return NULL;}//2.映射int *plcd = mmap(NULL,800*480*4,PROT_READ |  PROT_WRITE,MAP_SHARED,*fd,0);if(MAP_FAILED == plcd){perror("mmap fail");return NULL;}return plcd;
}/*Uninit_LCD:解初始化屏幕@fd:帧缓冲的文件描述符@plcd:返回值:无
*/
void Uninit_LCD(int fd,int *plcd)
{//1.解映射munmap(plcd,800*480*4);//2.关闭帧缓冲close(fd);
}void Lcd_draw_point(int x,int y,int color,int *plcd)
{if(NULL == plcd){printf("error:plcd == NULL\n");return ;}if(x>=0&&x<800&&y>=0&&y<480){*(plcd+800*y+x) = color;}
}
void Lcd_draw_matrx(int x,int y,int h,int w,int color,int *plcd)
{int i,j;if((x+w)>=0||(x+w)<=880||(y+h)>=0||(y+h)<=880)for(j=x;j<x+w;j++){for(i=y;i<y+h;i++){Lcd_draw_point(i,j,color,plcd);}}
}/*Bmp_display:在屏幕的指定的位置显示bmp图片@bmp_file:图片的路径名@x0 y0 图片左上角在屏幕上的坐标@plcd:帧缓冲映射区域的首地址返回值:-1 失败0  成功
*/
int Bmp_display(const char *bmp_file,int x0,int y0,int *plcd)
{if(plcd == NULL || !(x0>=0&&x0<800&&y0>=0&&y0<480)){return -1;}//1.打开图片int fd = open(bmp_file,O_RDONLY);if(-1 == fd){printf("%s",bmp_file);perror("open fail");return -1;}//2.判断到底是不是一张bmp图片char buf[4]={0};read(fd,buf,2);if(buf[0]!=0x42 || buf[1]!=0x4D){printf("NOT BMP\n");close(fd);return -1;}//3.解析图片 宽 高 色深lseek(fd,0x12,SEEK_SET);read(fd,buf,4);int width = buf[3]<<24 | buf[2]<<16 | buf[1]<<8 | buf[0];lseek(fd,0x16,SEEK_SET);read(fd,buf,4);int height = buf[3]<<24 | buf[2]<<16 | buf[1]<<8 | buf[0];lseek(fd,0x1c,SEEK_SET);read(fd,buf,2);short depth = buf[1]<<8 | buf[0];if(!(depth == 24 || depth == 32)){printf("NOT SUPPORT!\n");close(fd);return -1;}printf("%s:%d*%d depth:%d\n",bmp_file,width,height,depth);//4.获取像素数组int line_vaild_bytes=abs(width)*depth/8;int line_bytes;//一行总字节数=有效字节数+赖子数int laizi = 0;if(line_vaild_bytes%4){laizi = 4 - line_vaild_bytes%4;}line_bytes = line_vaild_bytes + laizi;int total_bytes = line_bytes*abs(height);//整个像素数组的大小//从文件中读取像素数组lseek(fd,54,SEEK_SET);unsigned char piexl[total_bytes];read(fd,piexl,total_bytes);//5.在屏幕的对应位置显示即可unsigned char a,r,g,b;int color;int i=0;int x,y;//遍历整个像素数组for(y=0;y<abs(height);y++){for(x=0;x<abs(width);x++){b=piexl[i++];g=piexl[i++];r=piexl[i++];if(depth==32){a=piexl[i++];}else{a=0;//不透明}color=a<<24|r<<16|g<<8|b;Lcd_draw_point(width>0?x+x0:x0+abs(width)-x-1,height>0?y0+abs(height)-y-1:y0+y,color,plcd);}//每一行末尾可能存在赖子i+=laizi;}close(fd);return 0;
}

touch.h

#ifndef __TOUCH_H__
#define __TOUCH_H__/*头文件*/
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <linux/input.h>//输入子系统#define UP 1
#define DOWN 2
#define LEFT 3
#define RIGHT 4
#define TOUCH_ERROR -1/*宏定义*/
#define TOUCH_FILE "/dev/input/event0"//获取坐标int Init_touch(void);
void  Uninit_touch(int touch_fd);
int get_usr_input_pro(int touch_fd,int *x1,int *y1,int *x2,int *y2);
int Get_slip_direction(int x1,int y1,int x2 ,int y2);void get_touch();/*get_usr_touch: 获取用户触摸屏输入的坐标值@x :保存 x轴的坐标值@y :保存 y轴的坐标值返回值 :无
*/
void get_usr_touch(int *x,int *y);/*功能 : 获取方向返回返回值 :-1 失败UP 1DOWN 2LEFT 3RIGHT 4
*/
int getway();#endif

touch.c

#include "touch.h"/*触摸屏初始化:Init_touch参数为空返回值:inttouch_fd:触摸屏的文件描述符
*/
int Init_touch(void)
{//1.打开触摸屏int touch_fd = open(TOUCH_FILE,O_RDONLY);if(-1 == touch_fd){perror("open touch fail");return -1;}return touch_fd;
}/*关闭触摸屏:Uninit_touch@touch_fd返回值:void
*/
void  Uninit_touch(int touch_fd)
{if(-1 == touch_fd){return ;}close(touch_fd);
}/*get_usr_input_pro:获取用户的对触摸屏的输入@x1 y1 @x2 y2@touch_fd返回值:int -1  失败0   成功
*/
int  get_usr_input_pro(int touch_fd,int *x1,int *y1,int *x2,int *y2)
{if(-1 == touch_fd){return -1;}struct input_event ev;//保存读取出来的信息*x1 = *y1 = *x2 =*y2 = -1;while(1){//1 读取输入事件int res = read(touch_fd,&ev,sizeof(ev));if(res != sizeof(ev)) // 判断结构体数据不符合要求 重新读{continue;//跳过本次循环,执行下一次循环}//2.2 通过判断结构体里面的成员坐标值if(ev.type == EV_ABS && ev.code == ABS_X) //获取x轴的坐标{if(-1 == *x1){*x1 = ev.value;  //只获取一次*x2 = ev.value;}*x2 = ev.value;         }if(ev.type == EV_ABS && ev.code == ABS_Y) //获取x轴的坐标{if(-1 == *y1){*y1 = ev.value;  //只获取一次*y2 = ev.value;}*y2 = ev.value;}if(ev.type == EV_KEY && ev.code == BTN_TOUCH && ev.value == 0 ) //手指松开{break;//一次获取}}return 0;
}/*  获取滑动的方向:Get_slip_direction@x1 y1 @x2 y2返回值:intLEFT RIGHT UP DOWN TOUCH_ERROR
*/
int Get_slip_direction(int x1,int y1,int x2 ,int y2)
{if(-1 == x1 || -1 == y1 || -1 == x2 || -1 == y2){return TOUCH_ERROR;}int direction; //方向if(abs((y2-y1)/(x2-x1)) >= 1) //上 或者 下{if(y2 > y1){return DOWN;}else{return UP;}}else{if(x2 > x1){return RIGHT;}else{return LEFT;}}}//打印坐标  测试
void get_touch()
{//1.打开触摸屏int fd = open("/dev/input/event0",O_RDONLY);if(-1 == fd){perror("open touch fail");return ;}//2.操作struct input_event ev;//保存读取出来的信息while(1){read(fd,&ev,sizeof(ev));printf("type =%d,code=%d,value=%d\n",ev.type,ev.code,ev.value);int x ,y ;if(ev.type == EV_ABS && ev.code == ABS_X )//触摸屏的x轴{x = ev.value *(1.0*800/1040);}if(ev.type == EV_ABS && ev.code == ABS_Y )//触摸屏的y轴{y = ev.value*(1.0*480/600);}printf("( %d , %d )\n",x,y);if(ev.type == EV_KEY && ev.code == BTN_TOUCH && ev.value == 0 ) //手指松开{break;//一次获取}}//3.关闭close(fd);}/*get_usr_touch: 获取用户触摸屏输入的坐标值@x :保存 x轴的坐标值@y :保存 y轴的坐标值返回值 :无
*/
void get_usr_touch(int *x,int *y)
{//1.打开触摸屏int fd = open("/dev/input/event0",O_RDONLY);if(-1 == fd){perror("open touch fail");return ;}//2.操作struct input_event ev;//保存读取出来的信息while(1){//2.1 读取输入事件int res = read(fd,&ev,sizeof(ev));int flag_x = 0, flag_y = 0;if(res != sizeof(ev)) // 判断结构体数据不符合要求 重新读{continue;//跳过本次循环,执行下一次循环}//2.2 通过判断结构体里面的成员获取坐标值if(ev.type == EV_ABS && ev.code == ABS_X) //获取x轴的坐标{*x = ev.value*(1.0*800/1040);flag_x = 1 ;if(flag_y){break;}}if(ev.type == EV_ABS && ev.code == ABS_Y) //获取y轴的坐标{*y = ev.value*(1.0*480/600);flag_y = 1 ;if(flag_x){break;}}if(ev.type == EV_KEY && ev.code == BTN_TOUCH && ev.value == 0 ) //手指松开{break;//一次获取}}//3.关闭触摸屏close(fd);}/*功能 : 获取方向返回返回值 :-1 失败UP 1DOWN 2LEFT 3RIGHT 4*/
int getway()
{//1.打开触摸屏int fd = open("/dev/input/event0",O_RDWR);if(-1 == fd){perror("open touch fail");return -1;}//2.操作struct input_event ev;//保存读取出来的信息int x0 = -1 ,y0 = -1 ;//初始坐标,把自身作为判断int x1 ,y1;while(1){//2.1 读取输入事件int res = read(fd,&ev,sizeof(ev));if(res != sizeof(ev)) // 判断结构体数据不符合要求 重新读{continue;//跳过本次循环,执行下一次循环}//2.2 通过判断结构体里面的成员坐标值if(ev.type == EV_ABS && ev.code == REL_X) //获取x轴的坐标{if(-1 == x0){x0 = ev.value;  //只获取一次}x1 = ev.value;}if(ev.type == EV_ABS && ev.code == REL_Y) //获取x轴的坐标{if(-1 == y0){y0 = ev.value;  //只获取一次}y1 = ev.value;}if(ev.type == EV_KEY && ev.code == BTN_TOUCH && ev.value == 0 ) //手指松开{break;//一次获取}}printf("start ( %d , %d ) , leave ( %d , %d )\n",x0,y0,x1,y1);int way; //方向if(abs((y1-y0)/(x1-x0)) >= 1) //上 或者 下{if(y1 > y0){printf("DOWN\n");way = DOWN;}else{printf("UP\n");way = UP;}}else{if(x1 > x0){printf("RIGHT\n");way = RIGHT;}else{printf("LEFT\n");way = LEFT;}}close(fd);return way;
}

main.c

#include <stdio.h>
#include "touch.h"
#include "lcd.h"int main()
{int touch_fd = Init_touch();int fd=-1;int* plcd = Init_LCD(&fd);//int x,y;// for(y=0;y>=10&&y<420;y++)// {//  for(x=0;x<=790&&x>=10;x++)//     {//         Lcd_draw_point(x,y,0x000000,plcd);//    }// }Bmp_display("./bmp/shang.bmp",20,420,plcd);Bmp_display("./bmp/xiay.bmp",174,420,plcd);Bmp_display("./bmp/sui.bmp",328,420,plcd);Bmp_display("./bmp/xun.bmp",482,420,plcd);Bmp_display("./bmp/ting.bmp",636,420,plcd);char *file_name[] = {"./bmp/1.bmp","./bmp/2.bmp","./bmp/3.bmp","./bmp/4.bmp","./bmp/5.bmp","./bmp/6.bmp","./bmp/7.bmp","./bmp/8.bmp","./bmp/9.bmp","./bmp/10.bmp"};    //存放图片地址和名字int x1=-1,y1=-1,x2=-1,y2=-1;int i=0;//存放图片顺序int x,y; //存放坐标值while(1){get_usr_touch(&x,&y);//显示区域if(x >= 10 && x <= 790 && y >= 10 && y<= 410){//测试滑动            if(-1 == get_usr_input_pro(touch_fd,&x1,&y1,&x2,&y2)){continue;}int direction;switch (direction = Get_slip_direction(x1,y1,x2,y2)){case UP:printf("UP\n");if(9 == i){i = -1;}printf("%d\n",i);Bmp_display(file_name[++i],10,10,plcd);break;case DOWN:printf("DOWN\n");if(0 == i){i = 10;}Bmp_display(file_name[--i],10,10,plcd);break; case RIGHT:printf("RIGHT\n");if(0 == i){i = 10;}Bmp_display(file_name[--i],10,10,plcd);                    break; case LEFT:printf("LEFT\n");if(9 == i){i = -1;}printf("%d\n",i);Bmp_display(file_name[++i],10,10,plcd);                  break; default:break;}}//上一张else if(x >= 20 && x <= 164  && y >= 420 && y<= 470){Bmp_display("./bmp/shang1.bmp",20,420,plcd);usleep(500);Bmp_display("./bmp/shang.bmp",20,420,plcd);if(0 == i){i = 10;}printf("return\n");Bmp_display(file_name[--i],10,10,plcd);}//下一张else if(x >= 174 && x <= 318 && y >= 420 && y<= 470){if(9 == i){i = -1;}printf("next\n");Bmp_display(file_name[++i],10,10,plcd);}//随机播放else if(x >= 328 && x <= 472 && y >= 420 && y<= 470){i = random()%10;Bmp_display(file_name[i],10,10,plcd);}//循环播放else if(x >= 482 && x <= 626 && y >= 420 && y<= 470){while(1){if(9 == i){i = -1;}Bmp_display(file_name[++i],10,10,plcd);sleep(1.5);}}//停止循环播放else if(x >= 420 && x <= 636 && y >= 470&& y<=780  ){printf("停止循环播放");}}Uninit_touch(touch_fd);Uninit_LCD(fd,plcd);return 0;
}

Day8_ElectronicAlbum相关推荐

最新文章

  1. 如何在Datawhale开源学习小程序中创建队伍?
  2. yum安装出现Error: Package: glibc-headers-2.17-157.el7.x86_64 (centos7.3)类似报错解决方案
  3. livebos--流程节点判断
  4. Ubuntu 安装JDK8
  5. Sublime Text3怎样在Deepin中配置CTags插件
  6. Jquery打叉怎么办
  7. python解释器、pycharm安装及环境变量配置
  8. 此网址已被限制 此网址使用了一个通常用于网络浏览以外目的的端口。出于安全原因,Firefox 取消了该请求。
  9. 通过 JavaScript 获取/设置元素样式的方法
  10. python批量替换文件_python实现文件名批量替换和内容替换
  11. UTAU - 完整无乱码汉化策略及资源配布
  12. ArcGIS矢量化并进行拓扑检查(附练习数据下载)
  13. 什么是平面设计?详细讲解平面设计
  14. 土壤数据库一些参数解释和补充说明
  15. ql的python学习之路-day5
  16. Note: further occurrences of HTTP request parsing errors will be logged at DEBUG level.错误解决
  17. MiniGui打开GridView控件
  18. 【IEEE-CPS出版,往届已检索】第二届计算机图形学、图像与虚拟化研究国际会议(ICCGIV 2022)
  19. 在NS-3中安装可视化工具NeAnim
  20. [Vue]如何实现一个简单的表格数据筛选查找 (根据ElementUI表格展示)(数组筛选)

热门文章

  1. 电脑开热点给手机七步法,买路由器的钱都省了
  2. linux var log目录作用,Linux系统/var/log/journal/垃圾日志清理 - 米扑博客
  3. Git中SSH公钥配置
  4. 什么是计算机的桌面,desktop是什么
  5. 韩顺平php文件下载详解
  6. 为知笔记,Ulysses和Effie哪个更适合记者?
  7. 短视频脚本要注意哪些要素?拍摄场景不能忘,配音也很重要
  8. 数学建模————统计问题之分类/聚类(二)
  9. 【91xcz】卸载Windows 8快速恢复原系统
  10. C 语言格式化输出函数中常用的格式符号