基于GEC6818开发板的相册

该代码实现了一个图片显示系统,包括图片的上下左右滑动切换、幻灯片播放以及缩略图显示。通过读取触摸事件获取滑动方向,控制图片的转换。此外,还提供了图片的四种动态切换效果:左滑、右滑、上滑、下滑。程序使用Linux的framebuffer设备文件进行屏幕操作,并通过/dev/input/event0获取触摸事件。
摘要由CSDN通过智能技术生成

一,实现的功能

1.图片的显示

2.上滑,下滑,左滑,右滑切换图片

3.幻灯片播放相册

4.显示图片的缩略图

二,代码实现

pic.h

#ifndef __PIC__H_
#define __PIC__H_

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <stdlib.h>
#include <unistd.h>
#include <linux/input.h>

typedef enum DIRECTION{
    UP,DOWN,LEFT,RIGHT
}DIRECTION;

typedef struct point{
	int x;
	int y;
}point;

struct node{
	char pics[20];
	struct node *next;
};

struct Linked{
	struct node *first;
	struct node *last;
	int nodeNum;
};

int save_color[800][800];
extern void add_node(struct Linked *l,struct node *p);//增加数据结点
extern struct Linked *Create_link(struct Linked *l);//创建链表存储图片文件名
void show_bmp(int x0,int y0,char * pic,int flag);//显示图片


extern void lcd_draw_point(int x,int y,int color);//画点
extern int get_slip_way();//获取滑动方式
void print_test(struct Linked *l);
void show_mulu(int x0,int y0,struct Linked *l);//显示目录
void lcd_draw_point_mulu(int w,int h,int x,int y,int color);//目录画点
point touch();//获取点击事件
void control();//控制整个程序的运行
int touch_bool();//判断是否点击
void show_left(int i,char *pic);//左滑显示下一张
void show_right(int i,char *pic);//右滑显示上一张
void show_up(int i,char *pic);//上滑显示下一张
void show_down(int i,char *pic);//下滑显示上一张

void play_pic(struct Linked * l);//幻灯片播放

void show_cril(int i,char *pic);//画圆显示


#endif

main.c

#include "pic.h"


int *plcd = NULL;
/*
	lcd_draw_point:画点
		@x:横坐标
		@y:纵坐标
		@color:颜色
*/

void lcd_draw_point(int x,int y,int color)
{
    if(x>=0 && x <800 && y >= 0 && y<480)
    {
        *(plcd+y*800+x) = color;
    }

}

int main()
{

	struct Linked *l = Create_link(l);
    int lcd_fd = open("/dev/fb0",O_RDWR);
    if(lcd_fd == -1)
    {
        perror("open error\n");
        return -1;
    }
    plcd = mmap(NULL,800*480*4,PROT_READ | PROT_WRITE, MAP_SHARED,lcd_fd,0);
    show_bmp(0,0,"mu.bmp",1);
    touch();
	show_mulu(0, 0,l);
	
    munmap(plcd,800*480*4);
    close(lcd_fd);
}

获取滑动方向,控制图片切换

#include "pic.h"

/*
	get_slip_way:获取滑动方向
*/

int get_slip_way()
{
    point p1;
    p1.x = -1;
    p1.y = -1;

    point p2;
    p1.x = -1;
    p1.y = -1;

    int fd = open("/dev/input/event0",O_RDWR);
    if(fd == 0)
    {
        perror("open error\n");
        return -1;
    }

    struct  input_event ev;

    int ret;
    int flag = 0;
    int count = 0;
    while(1)
    {
        ret = read(fd,&ev,sizeof(ev));
        if(ret != sizeof(ev))
        {
            close(fd);
            perror("read error");
            return -1;
        }
   
        //判断触摸事件,并获取X值
        if(ev.type == EV_ABS && ev.code == ABS_X)
        {
            if(p1.x < 0)
            {
                p1.x = ev.value;
            }
            else
            {
                p2.x = ev.value;
            }
        }
        if(ev.type == EV_ABS && ev.code == ABS_Y)
        {
            if(p1.y < 0)
            {
                p1.y = ev.value;
            }
            else
            {
                p2.y = ev.value;
            }
        }

        if(ev.type == EV_KEY && ev.code == BTN_TOUCH && ev.value==0)
        {
            int dt_x = abs(p1.x - p2.x);
            int dt_y = abs(p1.y - p2.y);

            if(dt_x > 2*dt_y)
            {
                if(p1.x > p2.x)
                {
                    return LEFT;
                }
                if(p1.x < p2.x)
                {
                    return RIGHT;
                }
            }
            else if (2*dt_x < dt_y)
            {
                if(p1.y > p2.y)
                {
                    return UP;
                }
                if(p1.y < p2.y)
                {
                    return DOWN;
                }
            }
            else
            {
                p1.x = -1;
                p1.y = -1; 
                p2.x = -1;
                p2.y = -1; 
            }
            
        }
    }
}

/*
	control:控制图片的转换


*/
void control()
{

	char pic[100] = {0};
	int i = 1;
	struct Linked *l = Create_link(l);
	while(1)
	{
		DIRECTION x = get_slip_way();
		switch (x)
		{
			case UP: 
				if(++i >= 14)
				{
					i = 1;
				}
				show_cril(i,pic);
				show_bmp(0,0,"100.bmp",1);
				break;
			case LEFT:
				if(++i >= 14)
				{
					i = 1;
				}
				show_left(i,pic);
				show_bmp(0,0,"100.bmp",1);
				break;
			case DOWN:
				if(--i == 0)
				{
					i = 13;
				}
				show_down(i,pic);
				show_bmp(0,0,"100.bmp",1);
				break;
			case RIGHT:
				if(--i == 0)
				{
					i = 13;
				}
				show_right(i,pic);
				show_bmp(0,0,"100.bmp",1);
				break;
		
			default:
				break;
		}

		point p = touch();
		printf("x = %d y = %d\n",p.x,p.y);
		if(p.x>=0&&p.x<90&&p.y>=0&&p.y<90)
		{
			show_mulu(0, 0, l);
			show_bmp(360, 0, "play.bmp", 1);
			p = touch();
			printf("x = %d y = %d\n",p.x,p.y);
			if(p.x>360&&p.x<=460&&p.y>=0&&p.y<=90)
			{

				play_pic(l);
			}
		}

	
		
	}


}

幻灯片播放

#include "pic.h"

/*
	play_pic:播放图片
		@l:存储数据的链表
*/

void play_pic(struct Linked *l)
{
	
	struct node *p = l->first;
	int flag = 1;//控制不同的播放方式
	char pic[100];
	int i = 1;
	while(p)
	{
		if(flag == 1)
		{
			show_down(i,pic);
			flag++;
		}else if(flag == 2)
		{
			show_left(i,pic);
			flag++;
		}else if(flag == 3)
		{
			show_up(i,pic);
			flag++;
		}else if(flag == 4)
		{
			show_right(i,pic);
			flag ++;
		}else if(flag == 5)
		{
			flag = 1;
		}
		
		i++;
 		p = p->next;
	}
	
}

保存图片到链表

#include "pic.h"
/*
	add_node:增加数据结点
		@l:要添加到的链表
		@p:需要添加的数据结点
*/
void add_node(struct Linked *l,struct node *p)
{
	if(l->first == NULL && l->last == NULL)
	{
		l->first = p;
		l->last = p;
		l->nodeNum++;
	}
	else
	{
		l->last->next = p;
		l->last = p;
		l->nodeNum++;
	}

}

/*
	Create_link:创建链表
		@l:初始化的链表
*/
struct Linked *Create_link(struct Linked *l)
{
	l = malloc(sizeof(*l));
	l->first = NULL;
	l->last = NULL;
	l->nodeNum = 0;
	int i = 1;
	while(1)
	{
		struct node *p = malloc(sizeof(*p));
		sprintf(p->pics,"%d.bmp",i);
		puts(p->pics);
		p->next = NULL;
		add_node(l,p);
		i++;
		if(i == 13)
		{
			break;
		}
	}

	return l;

}
/*
	print_test:打印链表数据
		@l:打印的链表
*/

void print_test(struct Linked *l)
{
	struct node *p = l->first;
	while(p)
	{
		puts(p->pics);
		p = p->next;
	
	}


}

显示图片

#include "pic.h"

/*
	show_cril:圆形切换
		@i:图片的名字
		@*pic:空数组用来存储完整文件名

*/
void show_cril(int i,char *pic)
{
	sprintf(pic,"%d.bmp",i);
	puts(pic);
	show_bmp(0, 0,pic,0);
	int num = 0;
	int r = 15;
	for(int k=0;k<35;k++)
	{
		for(int m=0;m<480;m++)
		{
			for(int n=0;n<800;n++)
			{
				if((m-240)*(m-240)+(n-400)*(n-400)<=r*r*num)
				lcd_draw_point(n, 479-m, save_color[m][n]);
			}
		}
		num = num+30;
	}


}

/*
	show_left:图片从右向左覆盖
		@i:图片的名字
		@*pic:空数组用来存储完整文件名

*/

void show_left(int i,char *pic)
{
	sprintf(pic,"%d.bmp",i);
	 puts(pic);
	show_bmp(0, 0,pic,0);
	for(int m=799;m>=0;m--)
	{
		for(int n=479;n>=0;n--)
		{

			lcd_draw_point(m, 479-n, save_color[n][m]);
		}
		usleep(5);
	}
}


/*
	show_up:图片从上向下覆盖
		@i:图片的名字
		@*pic:空数组用来存储完整文件名

*/

void show_up(int i,char *pic)
{
	sprintf(pic,"%d.bmp",i);
	puts(pic);
	show_bmp(0, 0,pic,0);
	for(int m=0;m<480;m++)
	{
		for(int n=0;n<800;n++)
		{
			lcd_draw_point(n, 479-m, save_color[m][n]);
		}
		usleep(5);
	}

}

/*
	show_down:图片从下向上覆盖
		@i:图片的名字
		@*pic:空数组用来存储完整文件名

*/

void show_down(int i,char *pic)
{
	sprintf(pic,"%d.bmp",i);
	 puts(pic);
	show_bmp(0, 0,pic,0);
	for(int m=479;m>=0;m--)
	{
		for(int n=0;n<800;n++)
		{
			lcd_draw_point(n, 479-m, save_color[m][n]);
		}
		usleep(5);
	}


}

/*
	show_right:图片从左向到覆盖
		@i:图片的名字
		@*pic:空数组用来存储完整文件名

*/

void show_right(int i,char *pic)
{
	sprintf(pic,"%d.bmp",i);
	show_bmp(0, 0,pic,0);
	for(int m=0;m<800;m++)
	{
		for(int n=0;n<480;n++)
		{

			lcd_draw_point(m, 479-n, save_color[n][m]);
		}
		usleep(5);
	}
}

/*
	show_bmp:显示图片
		@x0:初始横坐标
		@y0:初始纵坐标
		@*pic:图片文件名
		@flag:为0保存像素,为1立即显示

*/


void show_bmp(int x0,int y0,char * pic,int flag)
{
    int fd = open(pic,O_RDWR);
    int hight,width;
    short depth;
    unsigned char buf[4] = {0};

    lseek(fd,0x0A,SEEK_SET);
    read(fd, buf,4);
	int save = buf[3] <<24 | buf[2] <<16 | buf[1]<<8 |buf[0] <<0;
  
    lseek(fd,0x12,SEEK_SET);
    read(fd, buf,4);
    width = buf[3] <<24 | buf[2] <<16 | buf[1]<<8 |buf[0] <<0;
    
    lseek(fd,0x16,SEEK_SET);
    read(fd, buf,4);
    hight = buf[3] <<24 | buf[2] <<16 | buf[1]<<8 |buf[0] <<0;
    
    lseek(fd,0x1c,SEEK_SET);
    read(fd, buf,2);
    depth = buf[1] <<8 | buf[0];

	
    int laizi = 0;
    if((width/8) % 4 != 0)
    {
        laizi = 4 - (width/8)%4;
    }

    int  real_width = laizi + abs(width);
    int total_by = real_width *abs(hight) *(depth/8);

    unsigned char* pixel = malloc(total_by);

    lseek(fd,54,SEEK_SET);
    read(fd,pixel,total_by);
    int m ,n,i = 0;
    unsigned int a,r,g,b;
    int color;
    printf("hight= %d, width = & %d\n",hight,width);
    for(m = 0;m<abs(hight);m++)
    {
        for(n=0;n<abs(width);n++)
        {
            b = pixel[i++];
            g = pixel[i++];
            r = pixel[i++];

            if(depth == 24)
            {
                a = 0;
            }
            else if (depth == 32 )
            {
                a = pixel[i++];
            }
            color = a<<24 | r <<16 | g<<8 | b;
			save_color[m][n] = color;
			if(flag==1)
			{
           		 lcd_draw_point( width>0 ?  x0+n : x0+abs(width)-n-1,hight>0? y0+hight-m-1 : y0+m,color);
         	 }
        }
        i  = i +laizi;
        usleep(50);
    }

    free(pixel);
    close(fd);
}


/*
	show_bmp_small:显示目录缩略图
		@x0:初始横坐标
		@y0:初始纵坐标
		@*pic:图片文件名

*/

void show_bmp_small(double x0,double y0,char * pic)
{
    int fd = open(pic,O_RDWR);
    int hight,width;
    short depth;
    unsigned char buf[4] = {0};

    lseek(fd,0x0A,SEEK_SET);
    read(fd, buf,4);
	int save = buf[3] <<24 | buf[2] <<16 | buf[1]<<8 |buf[0] <<0;
  
    lseek(fd,0x12,SEEK_SET);
    read(fd, buf,4);
    width = buf[3] <<24 | buf[2] <<16 | buf[1]<<8 |buf[0] <<0;
    
    lseek(fd,0x16,SEEK_SET);
    read(fd, buf,4);
    hight = buf[3] <<24 | buf[2] <<16 | buf[1]<<8 |buf[0] <<0;
    
    lseek(fd,0x1c,SEEK_SET);
    read(fd, buf,2);
    depth = buf[1] <<8 | buf[0];

	
    int laizi = 0;
    if((width/8) % 4 != 0)
    {
        laizi = 4 - (width/8)%4;
    }

    int  real_width = laizi + abs(width);
    int total_by = real_width *abs(hight) *(depth/8);

    unsigned char* pixel = malloc(total_by);

    lseek(fd,54,SEEK_SET);
    read(fd,pixel,total_by);
    int m ,n,i = 0;
    unsigned int a,r,g,b;
    int color;
    for(m = 0;m<abs(hight);m=m+1)
    {
        for(n=0;n<abs(width);n=n+1)
        {
            b = pixel[i++];
            g = pixel[i++];
            r = pixel[i++];
			
            if(depth == 24)
            {
                a = 0;
            }
            else if (depth == 32 )
            {
                a = pixel[i++];
            }
            color = a<<24 | r <<16 | g<<8 | b;

       		lcd_draw_point( width>0 ?  (x0+n)/4.0 : (x0+abs(width)-n-1)/4.0,hight>0? (y0+hight-m-1)/3.0 : (y0+m)/3.0,color);
        }
        i  = i +laizi;
       
    }

    free(pixel);
    close(fd);
}


/*
	show_mulu:显示图片
		@x0:初始横坐标
		@y0:初始纵坐标
		@l :保存着图片文件名的链表

*/

void show_mulu(int x0,int y0,struct Linked *l)
{
	struct node *p = l->first;
	int w=0;
	int h=0;
	int flag = -1;
	while(p)
	{
		show_bmp_small(w*4, h*3, p->pics);
		w = w + 200;
		usleep(5);
		if(w==800)
		{
			w = 0;
			h = h +160;
		}
 		p = p->next;
	}
	show_bmp(360, 0, "play.bmp", 1);
	point p1 = touch();
	printf("x = %d y = %d\n",p1.x,p1.y);
	if(p1.x>360&&p1.x<=440&&p1.y>=0&&p1.y<=90)
	{

		play_pic(l);
	}
	if(p1.x>=0&&p1.x<200 && p1.y>=0&&p1.y<=160)
	{
		flag = 1;
	}
	if(p1.x>=200&&p1.x<400&& p1.y>=0&&p1.y<=160)
	{
		flag = 2;
	}
	if(p1.x>=400&&p1.x<600 && p1.y>=0&&p1.y<=160)
	{
		flag = 3;
	}
	if(p1.x>=600&&p1.x<800 && p1.y>=0&&p1.y<=160)
	{
		flag = 4;
	}
	if(p1.x>=0&&p1.x<200 && p1.y>=160&&p1.y<=320)
	{
		flag = 5;
	}
	if(p1.x>=200&&p1.x<400&& p1.y>=160&&p1.y<=320)
	{
		flag = 6;
	}
	if(p1.x>=400&&p1.x<600 && p1.y>=160&&p1.y<=320)
	{
		flag = 7;
	}
	if(p1.x>=600&&p1.x<800 && p1.y>=160&&p1.y<=320)
	{
		flag = 8;
	}
	if(p1.x>=0&&p1.x<200 && p1.y>=320&&p1.y<=480)
	{
		flag = 9;
	}
	if(p1.x>=200&&p1.x<400&& p1.y>=320&&p1.y<=480)
	{
		flag = 10;
	}
	if(p1.x>=400&&p1.x<600 &&  p1.y>=320&&p1.y<=480)
	{
		flag = 11;
	}
	if(p1.x>=600&&p1.x<800 &&  p1.y>=320&&p1.y<=480)
	{
		flag = 12;
	}

	char pic[32] = {0};
	sprintf(pic,"%d.bmp",flag);
	show_bmp(0,0,pic,1);
	show_bmp(0,0,"100.bmp",1);
	control();
	
	
}

触屏判断

#include "pic.h"

/*
	touch:获得点击事件
	@retval:点击的坐标

*/

point touch()
{
    point p;
    p.x = -1;
    p.y = -1;

    int fd = open("/dev/input/event0",O_RDWR);
    if(fd == 0)
    {
        perror("open error\n");
        return p;
    }

    struct  input_event ev;

    int ret;
    while(1)
    {
        ret = read(fd,&ev,sizeof(ev));
        if(ret != sizeof(ev))
        {
            close(fd);
            perror("read error");
            return p;
        }
   
        //判断触摸事件,并获取X值
        if(ev.type == EV_ABS && ev.code == ABS_X)
        {
            if(p.x < 0)
            {
                p.x = ev.value*(800.0/1024);//EV_ABS默认1024,600
            }
        }
        if(ev.type == EV_ABS && ev.code == ABS_Y)
        {
            if(p.y < 0)
            {
                p.y = ev.value*(480.0/600);
       
            }
        }

        if(p.x>=0&&p.y>=0)
        {
            close(fd);
            return p;
        }
    }
}

/*
	touch_bool:判断是否点击

*/

int touch_bool()
{
	point p;
	p.x = -1;
	p.y = -1;
	int fd = open("/dev/input/event0",O_RDWR);
    if(fd == 0)
    {
        perror("open error");
        return 0;
    }

    struct input_event ev;
    int ret;
	int flag = -1;
    while(1)
    {
    	ret = read(fd,&ev,sizeof(ev));
    	if(ret != sizeof(ev))
    	{
    		close(fd);
			perror("read error");
			return 0;
    	}
    	if(ev.type == EV_ABS && ev.code == ABS_X)
    	{
			return 1;
    	}

    	if(ev.type == EV_ABS && ev.code == ABS_Y);
    	{
			return 1;
    	}

    	if(p.x>=0 && p.y>=0)
    	{
			return 0;
    	}

    }
    
}

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

amireux512

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值