#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <unistd.h>
#include <sys/mman.h>
#include <string.h>
#include <sys/types.h>
#include <dirent.h>
#include <linux/input.h>
#include <time.h>
// #include "head4animation.h" 自定义用来实现切换图片效果的文件
//BMP文件头(14字节)
struct bitmap_header
{
int16_t type;// 位图文件的类型,必须为BM(1-2字节)
int32_t size;// 位图文件的大小,以字节为单位(3-6字节)
int16_t reserved1;// 位图文件保留字,必须为0(7-8字节)
int16_t reserved2;// 位图文件保留字,必须为0(9-10字节)
int32_t offbits;// 位图数据的起始位置,以相对于位图(11-14字节)
// 文件头的偏移量表示,以字节为单位
}__attribute__((packed));
//位图信息头(40字节)
struct bitmap_info
{
int32_t size;// 本结构所占用字节数(15-18字节)
int32_t width;// 位图的宽度,以像素为单位(19-22字节)
int32_t height;// 位图的高度,以像素为单位(23-26字节)
int16_t planes;// 目标设备的级别,必须为1(27-28字节)
int16_t bit_count;// 每个像素所需的位数,必须是1(双色),(29-30字节)
// 4(16色),8(256色)或24(真彩色)之一
int32_t compression;// 位图压缩类型,必须是 0(不压缩),(31-34字节)
// 1(BI_RLE8压缩类型)或2(BI_RLE4压缩类型)之一
int32_t size_img;// 位图的大小,以字节为单位(35-38字节)
int32_t X_pel;// 位图水平分辨率,每米像素数(39-42字节)
int32_t Y_pel;// 位图垂直分辨率,每米像素数(43-46字节)
int32_t clrused;// 位图实际使用的颜色表中的颜色数(47-50字节)
int32_t clrImportant;// 位图显示过程中重要的颜色数(51-54字节)
}__attribute__((packed));
int n;//图片个数
char pic[20][20];//存放所有为bmp图片的文件
void found_bmp(char const *file_name);
void display_pic();
int next_pic(int *x1);
int p= 0,v =0;
int main(int argc, char const *argv[])
{
found_bmp(argv[1]);
display_pic();
return 0;
}
// 找到所有bmp类型的图片放在数组中
void found_bmp(char const *file_name)
{
DIR *dp = opendir(file_name);
if (dp == NULL)
{
return ;
}
struct dirent *d;
int i = 0;
while(d = readdir(dp))
{
if (!strcmp(d->d_name, ".") || !strcmp(d->d_name, ".."))
{
continue;
}
if (d == NULL)
{
break;
}
sprintf(pic[i],"%s/%s",file_name,d->d_name);
printf("%s ",pic[i]);
i++;
n++;
}
closedir(dp);
}
void display_pic()
{
//打开液晶屏幕文件
int lcd_fd = open("/dev/fb0", O_RDWR);
if (lcd_fd == -1)
{
perror("open pm");
return ;
}
//(1)申请内存映射
int *FB = mmap(NULL, 800*480*4, PROT_WRITE|PROT_READ, MAP_SHARED, lcd_fd, 0);
// 利用循环 并显示
int k = 0;
unsigned long (*buf)[800] = calloc(800*480,4);
// int x=0,y=0;
while(1)
{
// 打开图片文件
int bmp_fd = open(pic[k], O_RDONLY);
if (bmp_fd == -1)
{
perror("open bmp");
}
//读取文件头
struct bitmap_header bh;
struct bitmap_info bi;
read(bmp_fd, &bh, sizeof(bh));
read(bmp_fd, &bi, sizeof(bi));
printf("\n读取到第%d张--->w = %d, h = %d, bit = %d\n", k,bi.width, bi.height, bi.bit_count);
//将RGB数据读出来
char RGB[800*480*3];
read(bmp_fd, &RGB, 800*480*3);
//将RGB转成ARGB
unsigned int ARGB[800*480];
for (int i = 0; i < 800*480; ++i)
{
ARGB[i] = RGB[i*3+0]<<0|RGB[i*3+1]<<8|RGB[i*3+2]<<16;
}
//y坐标翻转
for (int x = 0; x < 800; ++x)
{
for (int y = 0; y < 480; ++y)
{
buf[y][x] = ARGB[(479-y)*800+x];
}
}
//用内存映射方式显示
if (FB == MAP_FAILED)
{
perror("mmap");
return ;
}
while(v == p)
{
srand(time(NULL));
v = rand()%4;
printf("我在寻早不同的值\n");
}
p = v;//确保不重复
switch(v)
{
case 0:printf("----0----"); falling_down_in(lcd_fd, buf); break;
case 1:printf("----1----"); floating_up_in(lcd_fd, buf); break;
case 2:printf("----2----"); left2right_in(lcd_fd, buf); break;
case 3:printf("----3----"); right2left_in(lcd_fd, buf); break;
}
int t;//接收x
int f = next_pic(&t);//接收y
printf("坐标x1 = %d\n", t);
printf("坐标y1 = %d\n", f);
if (t >950 && f< 50)
{
printf("返回到第一张\n");
printf("-----------------坐标x1------------%d\n", t);
printf("-----------------坐标y1------------%d\n", f);
k = 0;
continue;
}
if (t<50 && f<50)
{
printf("返回到最后一张\n");
printf("-----------------坐标x1------------%d\n", t);
printf("-----------------坐标y1------------%d\n", f);
k = n-1;
continue;
}
if (t > 980 && f> 570)
{
printf("结束放映\n");
printf("-----------------坐标x1------------%d\n", t);
printf("-----------------坐标y1------------%d\n", f);
break ;
}
if (t>512)
{
k++;
if (k == n)
{
k = 0;
}
}
else
{
k--;
if(k == -1)
{
k = n-1;
}
}
// munmap(FB, 800*480*4);//不要释放内存映射
close(bmp_fd);
// close(lcd_fd);//不可以关闭屏幕资源
}
}
int next_pic(int *x1)
{
// 打开触摸屏
int ts_fd = open("/dev/input/event0", O_RDONLY);//gec6818下的触摸屏文件
if (ts_fd == -1)
{
perror("open");
return 0;
}
struct input_event input_info;
while(1)
{
//这里会产生阻塞
read(ts_fd, &input_info, sizeof(input_info));
switch(input_info.type)
{
case EV_SYN:printf("---------SYN-------\n");break;
case EV_ABS://触摸屏事件
switch(input_info.code)
{
case ABS_X: *x1= input_info.value;break;
case ABS_Y: return input_info.value;
// case ABS_PRESSURE:
// printf("p = %d\n", input_info.value);return input_info.value;
}
default:break;
}
}
}
/* 该部分为显示效果的代码 如需实现请自行调用 或者重新创建一个c文件在调用
#include <linux/input.h>
#include "head4animation.h"
#include <unistd.h>
void floating_up_in(int lcd, unsigned long (*image)[WIDTH])
{
unsigned long (*FB)[WIDTH] = mmap(NULL, SCREEN_SIZE * 4,
PROT_READ | PROT_WRITE, MAP_SHARED, lcd, 0);
int i = 0;
while(1)
{
memcpy(&FB[HEIGHT-i-1][0], &image[0][0],
WIDTH*4*(i+1));
if(i >= HEIGHT-1)
break;
usleep(80);
i++;
}
}
void right2left_in(int lcd, unsigned long (*image)[WIDTH])
{
unsigned long (*FB)[WIDTH] = mmap(NULL, SCREEN_SIZE * 4,
PROT_READ | PROT_WRITE, MAP_SHARED, lcd, 0);
int i, j;
for(i=0; i<WIDTH; i++)
{
for(j=0; j<HEIGHT; j++)
{
memcpy(&FB[j][WIDTH-1-i], &image[j][0],4*(i+1));
}
usleep(80);
}
}
void left2right_in(int lcd, unsigned long (*image)[WIDTH])
{
unsigned long (*FB)[WIDTH] = mmap(NULL, SCREEN_SIZE * 4,
PROT_READ | PROT_WRITE, MAP_SHARED, lcd, 0);
int i, j;
for(i=0; i<WIDTH; i++)
{
for(j=0; j<HEIGHT; j++)
{
memcpy(&FB[j][0], &image[j][WIDTH-1-i],4*(i+1));
}
usleep(80);
}
}
*/