//加载jpg的接口需要自己定义(网上下载jpeg库)
#include <stdio.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <dirent.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <linux/input.h>
#include "touch.h"
//注意:该程序支持上下左右滑动,但是单击可能会得不到内容
int lcd_fd=0;
int ts_fd =0;
unsigned int *FB=NULL;//提前声明的映射内存变量名(由于是全局变量,谨慎使用)
//------链表定义区域------------------------------------
struct node
{
char data[1024]; //数据域(按需求定义)
struct node *next; //后驱指针,保存后面节点的地址
struct node *prev; //前驱指针,保存前面节点的地址
};
//头插
void add_last(struct node *head,char *str)
{
//1.创建新节点
struct node *new = malloc(sizeof(struct node));
new->next = NULL;
new->prev = NULL; //循环起来了
strcpy(new->data,str);
//2.插入节点
head->prev->next = new;
new->prev = head->prev;
head->prev = new;
new->next = head;
}
//删除链表中的节点
void del_node(struct node*head,char *str)
{
//指向头节点
struct node *pos = head->next;
//查找需要删除的节点
while(pos!= head)
{
if(strcmp(pos->data,str) == 0) //找到需要删除的数据
{
//删除节点
pos->prev->next = pos->next;
pos->next->prev = pos->prev;
//把需要删除的节点完全与链表脱离关系
struct node *tmp = pos;
pos = pos->prev; //回退
tmp->next = NULL;
tmp->prev = NULL;
free(tmp);
}
pos = pos->next;
}
return ;
}
//-----------获取文件信息区域------------------
//检索系统中的 jpg 文件
int read_pic(char *dir_path,struct node *head)
{
//读取目录中的图片
DIR *dp = opendir(dir_path);
if(dp==NULL)
{
return -1;
}
//读取目录中的文件名
while(1)
{
struct dirent *msg=readdir(dp);
if(msg == NULL)
{
break;
}
//判断名字
if(msg->d_name[0] == '.')
{
continue; //跳过隐藏文件
}
//判断是否为目录是的话就继续读取
if(msg->d_type == DT_DIR) //目录
{
//拼接路径
char path[2096]={0};
sprintf(path,"%s/%s",dir_path,msg->d_name);
//递归调用
read_pic(path,head);
}
if(msg->d_type == DT_REG) //普通文件
{
if(strstr(msg->d_name,".jpg") )
{
//拼接为绝对路径
char path[2096]={0};
sprintf(path,"%s/%s",dir_path,msg->d_name);
//把处理后的图片名字挂载到链表中
add_last(head,path);
}
}
}
//关闭目录
closedir(dp);
}
/* //获取文件大小 (拓展功能)
int get_file_size(char *file_path)
{
int fd = open(file_path,O_RDWR);
if(fd < 0)
{
// perror("");
return 0;
}
int size=lseek(fd,0,SEEK_END);
close(fd);
return size;
} */
//---------显示屏区域--------------------------
//初始化LCD
int init_lcd_ts()
{
//打开LCD设备文件
lcd_fd = open("/dev/fb0", O_RDWR);
if(lcd_fd == -1)
{
perror("lcd open failed");
return 0;
}
//FB指向的就是每个aRGB像素
FB = mmap(NULL, 4*800*480, PROT_READ | PROT_WRITE, MAP_SHARED,lcd_fd,0);
if(FB == MAP_FAILED)
{
perror("mmap failed");
return 0;
}
}
//释放LCD TS
void free_lcd()
{
close(lcd_fd);
munmap(FB,4*800*480);
close(ts_fd);
}
//清屏
void clean_lcd()//FB全局变量已在首部定义
{
int i;
for( i=0;i<800*480;i++)
{
*(FB+i) = 0xffffff;
}
}
void play( struct node *head)
{
struct node *pos = head->next;
clean_lcd();//先清屏后显示
readjpg(pos->data);
while(1)
{
int b = 0;
b = GetDirection();//获得读取到的手势(上滑,下滑,左滑,右滑)
printf("%d\n",b);
switch(b)
{
case 1://上滑
{
//printf("test!\n");
pos = pos->prev;
printf("%s\n",pos->data);
printf("上滑\n");
if(strstr(pos->data,".jpg"))//如果是目标文件,输出其链表中对应的数据(文件名)
{
readjpg(pos->data);
}
sleep(1);
break;
}
case 2://下滑
{
pos = pos->next;
printf("下滑\n");
printf("%s\n",pos->data);
if(strstr(pos->data,".jpg"))
{
readjpg(pos->data);
}
break;
}
case 3://左滑
{
pos = pos->prev;
printf("%s\n",pos->data);
printf("左滑\n");
if(strstr(pos->data,".jpg"))
{
readjpg(pos->data);
}
sleep(1);
break;
}
case 4://右滑
{
pos = pos->next;
printf("右滑\n");
printf("%s\n",pos->data);
if(strstr(pos->data,".jpg"))
{
readjpg(pos->data);
}
break;
}
default :
printf("单击我可不理你\n");
break;
}
}
}
//---------主函数区域-----------------------------
int main(int argc,char *argv[])
{
//创建一个链表的头节点
struct node *head = malloc(sizeof(struct node));
head->next = head;
head->prev = head; //循环起来了
bzero(head->data,1024);
//初始化LCD
init_lcd_ts();
//读取用户输入的目录
read_pic(argv[1],head);
//显示主界面
while(1)
{
read_pic(argv[1],head);
play(head);
}
return 0;
}
//下面是依赖的头文件
#ifndef __TOUCH_H
#define __TOUCH_H
#define UP 1
#define DOWN 2
#define LEFT 3
#define RIGHT 4
//宏定义
//设备文件
#define TOUCH_PATH "/dev/input/event0"//不同设备的话,设备文件路径可能不同(此处可以修改)
void readjpg(char *s);
int GetDirection()
{
//1.打开触摸屏
//lcd_init();
int fd = open(TOUCH_PATH,O_RDONLY);//只读打开
if(fd<0)
{
perror("open fail");
return 0;
}
int x_start=-1,y_start=-1; //坐标的初值
int x_end = -1,y_end = -1; //坐标终点
struct input_event ev;
while(1)
{
//2.不停地从文件中读取数据
read(fd, &ev, sizeof(struct input_event));
//3.解析数据
if(ev.type == EV_ABS) //触摸事件
{
if(ev.code == ABS_X)
{
if (-1 == x_start) //x轴
{
x_start = ev.value; //起点
}
x_end = ev.value; //终点
}
if(ev.code == ABS_Y) //y轴
{
if (-1 == y_start)
{
y_start = ev.value;
}
y_end = ev.value; //终点
}
if(ev.code ==ABS_PRESSURE && ev.value == 0)
{
if(x_start != -1 && y_start != -1)
{
break;
}
}
}
if(ev.type == EV_KEY && ev.code == BTN_TOUCH && ev.value == 0) //按键事件
{
if(x_start != -1 && y_start != -1)
{
break;
}
}
if (abs(x_end - x_start) > abs(y_end - y_start))//x轴的绝对值位移大于y轴(说明是左右滑动)
{
if (x_end - x_start > 0)//根据x位移的正负来判断是左滑还是右滑
{
return 4;
}
else
{
return 3;
}
}
if (abs(x_end - x_start) < abs(y_end - y_start))//与上述左滑右滑类比
{
if (y_end - y_start > 0)
{
return 2;
}
else
{
return 1;
}
}
}
//打印坐标
printf("%d , %d\n", x_end, y_start);
//4.关闭触摸屏
// lcd_close();
}
#endif
[源代码如下附赠现成图片](https://download.csdn.net/download/HBlXN/86402976)
数码相册的实现(手势切换图片,用链表加快效率,jpeg解码)
最新推荐文章于 2024-10-16 19:19:52 发布
这个程序实现了在Linux环境下遍历指定目录及其子目录中的jpg图片文件,并将文件名存储到链表中。支持通过LCD显示屏显示图片,并结合触摸屏手势(上滑、下滑、左滑、右滑)进行图片切换。程序还提供了链表的增删功能,但不支持单击操作。
摘要由CSDN通过智能技术生成