数码相册的实现(手势切换图片,用链表加快效率,jpeg解码)

这个程序实现了在Linux环境下遍历指定目录及其子目录中的jpg图片文件,并将文件名存储到链表中。支持通过LCD显示屏显示图片,并结合触摸屏手势(上滑、下滑、左滑、右滑)进行图片切换。程序还提供了链表的增删功能,但不支持单击操作。
摘要由CSDN通过智能技术生成
//加载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)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值