一,实现的功能
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;
}
}
}