天天看点

使用6818开发板进行触屏控制图片功能:加载图片目录、自动播放、删除、上一张、下一张、退出

#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>

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 ;
	
}
 
//获取文件大小 
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;
}
//检索系统中的 bmp 文件
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,".bmp") )
				{  
					//拼接为绝对路径 
				   char path[2096]={0};  
				   sprintf(path,"%s/%s",dir_path,msg->d_name);
					//把处理后的图片挂载到链表中 
					add_last(head,path);
				}
			
			}	
	}
	
	//关闭目录
	closedir(dp);
	
}

//初始化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;
	}
	
		//1.打开触摸屏设备文件
	  ts_fd=open("/dev/input/event0",O_RDWR);
		if(ts_fd < 0)
		{
			perror("");
			return -1;
		}
}

//释放LCD TS 
void free_lcd()
{	
	close(lcd_fd);
	munmap(FB,4*800*480);
	close(ts_fd);
}

//图片处理
int show_bmp(char *pic)
{

	//1.打开BMP 图像 
	//printf("测试:%s\n",pic);
	int  bmp = open(pic,O_RDWR);
		if(bmp < 0 )
		{
			perror("");
			return -1;
		}
	
	//2.读取BMP图片的头信息 
	unsigned char head[54];
	read(bmp,head,54);
	
	//3.获取长度与宽度   
	//head[18]  , head[19]  , head[20]  , head[21] //表示图像的宽度
	unsigned int kuan  =    head[18] |  head[19] << 8 | head[20] << 16 | head[21]<<24;
	unsigned int gao  =   head[22] |  head[23] << 8 | head[24] << 16 | head[25]<<24;
	printf("宽=%d,高=%d\n",kuan,gao);
	//1.根据宽和高  处理图像  转换成  32 位图
	unsigned char  buf[kuan*gao*3]; 
	read(bmp,buf,sizeof(buf));
	
	unsigned char  *p = buf; 
	int color[kuan*gao]; 
	
	int i;
	for( i=0;i<kuan*gao;i++)
	{
		 unsigned char b  = *p++; //b  
		 unsigned char g  = *p++;//g 
		 unsigned char r  = *p++;//r 
		 unsigned char a  = 0; 
		 
		 color[i]  =  a << 24 | r << 16  |  g << 8  | b;  //得到一个32位色 
	};
	
	//2.把处理后 的图像显示到 LCD 设备中 
      unsigned  int  *lcd = FB;
	
	  //判断宽和高 
	  if(kuan < 800 && gao < 480)
	  {
		 //求中间点 
		 int  x =  (800 - kuan)/2; 
		 int  y =  (480 - gao) /2;
		 //LCD偏移到中间点 
		 lcd   =   lcd + x + y*800;  
	  }
	
 int x, y;
	for(y=0; y<gao; y++)
	{
		for(x=0; x<kuan; x++)
		{
			if(x < 800 && y < 480)  //防止图像超出LCD最大的显示范围
			{
			   *(lcd + x  +y*800) = color[x+kuan*(gao-1-y)];  //赋值一行数据     
									 
			}
		}				
	}
	// 5.关闭	//关闭bmp文件描述符
	close(bmp);
	//printf("--------1------");
}

//返回 1  2  3  4  //确定点击的位置
int get_xy()
{
	//2.读取输入事件到 输入模型中 
	int x=0,y=0;
	int  p = 0;
	 while(1)
	{	 
		struct input_event  ts;
		read(ts_fd,&ts,sizeof(ts));
		//3.利用事件值处理获取到的坐标点
		if(ts.type ==  EV_ABS  && ts.code == ABS_X)  //X轴的坐标点 
		{
			  x = ((ts.value*800)/1024);
			  p = 0;
		}

		if(ts.type ==  EV_ABS  && ts.code == ABS_Y)  //Y轴的坐标点 
		{
			y = ((ts.value*480)/600);
			p = 1;
		}
		//打开X Y 坐标的
		if(x> 0 && y > 0)
		if(p == 1)
		{
			printf("x=%d,y=%d\n",x,y);
			
			if((x > 300 && x < 490) &&(y > 180 && y < 300) )
			{
				
				return 1; //加载
			}
			else if((x > 80 && x < 200) &&(y > 380 && y < 480) )
			{
				return 2; //自动
				
			}
			else if((x > 290 && x < 450) && (y > 380 && y < 480))
			{
				return 3;  //手动
				
			}
			else if((x > 0 && x < 100)&&(y > 0 && y < 480))
			{
				return 4;  //退出
				
			}
			
			x = 0; 
			y = 0;
		}
	}
}
//手动播放
int ctrl_play()
{
	//show_bmp("pick.bmp");
	//2.读取输入事件到 输入模型中 
	int x=0,y=0;
	int p = 0;
	 while(1)
	 {	 
		struct input_event  ts;
		read(ts_fd,&ts,sizeof(ts));

		//3.利用事件值处理获取到的坐标点
		if(ts.type ==  EV_ABS  && ts.code == ABS_X)  //X轴的坐标点 
		{
			 x = ((ts.value*800)/1024);
			  p =0;
		}

		if(ts.type ==  EV_ABS  && ts.code == ABS_Y)  //Y轴的坐标点 
		{
			y = ((ts.value*480)/600);
			p =1;
		}
		

		//打开X Y 坐标的
		if(x> 0 && y > 0)
		if(p == 1)
		{
			printf("x=%d,y=%d\n",x,y);
			//删除按钮
		    
			 if(x > 200 && x < 400  && y > 330 && y < 480)
			{
				return 3;  //退出
				
			}
			if(x > 0 && x < 400  && y > 100 && y < 300)
			{
				
				return 1; //上一张
			}
			else if(x > 400 && x < 800  && y > 100 && y < 300 )
			{
				return 2; //下一张
				
			}
		}
	 }
}

//清屏
void clean_lcd()
{
	int i;
	for( i=0;i<800*480;i++)
	{
		
		*(FB+i)	 =  0xffffff;
	}
		
}
 void show(struct  node *head)
 { 
	struct  node  *pos  = head->next; //指向第一个节点

	while(pos != head)  //因为当 pos == head 的时候该循环链表 已经跑了一遍
	{
		printf("%s\n",pos->data);
		if(strstr(pos->data,".bmp"))
		{
			//显示bmp
			clean_lcd();
			show_bmp(pos->data);	
		}
		
		
		pos = pos->next;
		
		sleep(1);
	}
			 
 }
 //手动播放
 void  play( struct  node *head)
 {
	struct  node *pos = head->next;
	
	//显示bmp
	clean_lcd();
	show_bmp(pos->data);	
	
	while(1)
   {	
		int b = ctrl_play();
		switch(b)
		{
			case 1:
			{
				pos  =  pos->prev;
				if(strstr(pos->data,".bmp"))
				{
					show_bmp(pos->data);	
				}
				sleep(1);
				break;
			}
			case 2:
			{
				pos  =  pos->next;
				if(strstr(pos->data,".bmp"))
				{
					show_bmp(pos->data);	
				}
				break;
			}
			case 3:
			{
				return ;
				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);
	//显示主界面 
	show_bmp("pick.bmp");
	
	while(1)
	{
		 //获取点击的坐标位置
		int a = get_xy();
		
		switch(a)
		{
			case 1: 
			{
				printf("加载图片\n");
				read_pic(argv[1],head);
				printf("加载完毕!!!\n");
				break;
			}
			case 2: 
			{
				printf("自动播放\n");
				show(head);
				show_bmp("pick.bmp");
				printf("自动播放完毕");
				break;
			}
			case 3: 
			{
				printf("手动浏览\n");
				
				play(head);
				show_bmp("pick.bmp");
				printf("手动结束\n");
				break;
			}
			case 4: 
			{
				printf("退出程序\n");
				break;
			}

			
		}
	}
	
	show(head);
	return 0;
}


           

继续阅读