数码相册项目的实现

本人因为此阶段精力有限,没有时间去整理代码格式,还请见谅。

//功能;自动左右切换,每一秒切换一次;自动切换

#include<stdio.h>

#include <sys/types.h>

#include <dirent.h>

#include<sys/stat.h>

#include<unistd.h>

#include<string.h>

#include<stdlib.h>

#include <fcntl.h>

#include <linux/input.h>

#include <sys/ioctl.h>

#include <linux/fb.h>

#include <sys/mman.h>

#include <jpeglib.h>

int fd;

int *plcd=NULL;

void LCD_Draw_Point(int x,int y,int color)

{

if(x >=0 && x < 800 && y >=0 && y < 480)

{

*(plcd + 800*y + x) = color;

}

}

 

void bmp_display(char *pathname)

{

int fdBmp;

int w,h;

unsigned char buf[4];

int color_depth;

 

//打开对应的文件

fdBmp = open(pathname,O_RDONLY);

if(fdBmp<0)

{

perror("bmp open fail");

return;

}

//判断是不是BMP图片

read(fdBmp,buf,2);

if(buf[0] != 0x42  || buf[1] != 0x4d)

{

printf("This is not a BMP picture\n");

return;

}

//读图片的宽度

lseek(fdBmp,0x12,SEEK_SET);

read(fdBmp,buf,4);

w = buf[3] << 24 | buf[2] << 16 | buf[1] << 8 | buf[0];

//读图片的高度

lseek(fdBmp,0x16,SEEK_SET);

read(fdBmp,buf,4);

h = buf[3] << 24 | buf[2] << 16 | buf[1] << 8 | buf[0];

 

printf("w=%d h=%d\n",w,h);

 

//读图片的色深

lseek(fdBmp,0x1c,SEEK_SET);

read(fdBmp,buf,2);

color_depth = buf[1] << 8 | buf[0];

 

//计算图片数据的大小

int size = abs(w*h*color_depth/8) ;

 

//分配用来保存图片数据的内存空间

unsigned char *pixel = malloc(size);

lseek(fdBmp,54,SEEK_SET);

read(fdBmp,pixel,size);

 

int x,y;

int i=0;

unsigned char a,r,g,b;

int color;

 

for(y=0;y < abs(h); y++)

{

for(x=0;x<abs(w);x++){

b = pixel[i++];

g = pixel[i++];

r = pixel[i++];

a = (color_depth == 32) ? pixel[i++] : 0;

color = a << 24 | r << 16 | g << 8 | b; //组合成一个新的颜色值ARGB

int dy = h > 0 ? (h - 1 - y) : y; //判断图片是从左下角还是左上角开始显示

LCD_Draw_Point(x,dy,color);

}

}

free(pixel);

close(fdBmp);

}

 

void jpeg_display(char *pathname)

{

 

//1)、分配并且初始化一个jpeg的解压对象

 

struct jpeg_decompress_struct cinfo;  //jpeg解压对象

struct jpeg_error_mgr jerr; //jpeg解压出错处理的结构体

cinfo.err = jpeg_std_error(&jerr); //初始化这两个对象

jpeg_create_decompress(&cinfo);

 

//2)、将需要解压的JPEG图片读进来

 

 

FILE * infile;

if ((infile = fopen(pathname, "r")) == NULL) {

    fprintf(stderr, "can't open \n");

    exit(1);

}

jpeg_stdio_src(&cinfo, infile);

 

//3)、读取JPEG的头信息

jpeg_read_header(&cinfo, TRUE);

 

//4)、设置解压的参数,如果不需要修改,就不需要做什么,采用默认的解压参数就可以了。

 

//5)、调用对应的函数,进行解压操作

//printf("cinfo.output_components=%d cinfo.output_height=%d\n",cinfo.output_components,cinfo.output_height);

jpeg_start_decompress(&cinfo);

printf(" cinfo.output_height=%d\n",cinfo.output_height);

printf("components=%d width=%d\n",cinfo.output_components,cinfo.output_width);

 

unsigned char *buffer = malloc(cinfo.output_width * cinfo.output_components);

 

//6)、逐行读入JPEG的数据,并且解压

int x,y=0;

while ( cinfo.output_scanline < cinfo.output_height )

{

y=cinfo.output_scanline;

jpeg_read_scanlines(&cinfo, &buffer, 1);

 

unsigned char a,r,g,b;

int color;

unsigned char *p = buffer;

for(x=0;x < cinfo.output_width;x++)

{

if(cinfo.output_components == 3)

{

a=0;   //如果cinfo.output_components == 3 它只有RGB的值

}

else

{

a=*p++; //否则是ARGB的格式

}

r = *p++;

g = *p++;

b = *p++;

color = a << 24 | r << 16 | g << 8 | b;

if(y<480 && x < 800)

{

LCD_Draw_Point(  x, y, color);

}

}

 

}

 

//7)、调用函数完成解压操作

jpeg_finish_decompress(&cinfo);

 

//8)、释放JPEG解压对象

jpeg_destroy_decompress(&cinfo);

fclose(infile);

 

}

struct picnode

{

char name[32];

struct picnode *pre;

struct picnode *next;

int mode;

};

struct pichead

{

struct picnode *next;

struct picnode *pre;

 

};

struct pichead *creathead()

{

struct pichead *dhead=(struct pichead *)malloc(sizeof(*dhead));

dhead->next=NULL;

dhead->pre=NULL;

return dhead;

 

}

void addnode(struct pichead *head,struct picnode *p)

{

 

if(head==NULL||p==NULL)

{

return;

}

if(head->next==NULL)

{

head->next=p;

head->pre=p;

}

else

{

head->pre->next=p;

p->pre=head->pre;

head->pre=p;

}

}

void printklink(struct pichead *head)//打印链表,调用jpeg图片显示

{

struct picnode *p=head->next;

while(p)

{

printf("%s %d\n",p->name,p->mode);

if(p->mode==1)

{

jpeg_display(p->name);

}

else if(p->mode==0)

{

bmp_display(p->name);

}

sleep(1);

p=p->next;

}

printf("********\n");

p=head->pre;

while(p)

{

printf("%s %d\n",p->name,p->mode);

if(p->mode==1)

{

jpeg_display(p->name);

}

else if(p->mode==0)

{

bmp_display(p->name);

}

sleep(1);

p=p->pre;

}

}

 

 

 

struct pichead * dirsize(char *pathname,struct pichead *head)//把图片路径放入链表;

{

DIR *dir;

dir=opendir(pathname);

struct stat st;

char filename[520];

int size=0;

if(dir==NULL)

{

perror("open dir fail");

}

struct dirent *dirp=NULL;

while(dirp=readdir(dir))

{

 

if(strcmp(dirp->d_name,".")==0||strcmp(dirp->d_name,"..")==0)//过滤掉当前目录和上一级目录

{

continue;

}

sprintf(filename,"%s/%s",pathname,dirp->d_name);

if(strcmp(filename+strlen(filename)-4,".jpg")==0)

{

// printf("==> %s\n",filename);

struct picnode *p=(struct picnode *)malloc(sizeof(*p));

strcpy(p->name,filename);

p->mode=1;

p->next=NULL;

p->pre=NULL;

addnode(head,p);

}

if(strcmp(filename+strlen(filename)-4,".bmp")==0)

{

// printf("==> %s\n",filename);

struct picnode *p=(struct picnode *)malloc(sizeof(*p));

strcpy(p->name,filename);

p->mode=0;

p->next=NULL;

p->pre=NULL;

addnode(head,p);

}

stat(filename,&st);

if(S_ISDIR(st.st_mode))

{

dirsize(filename,head);

}

else

{

size+=st.st_size;//可以不要,用来计算文件总大小的;

}

}

closedir(dir);

return head;

}

int main(int argc,char *argv[])

{

fd = open("/dev/fb0",O_RDWR);

if(fd < 0)

{

perror("open lcd fail");

return -1;

}

struct fb_var_screeninfo fbinfo;

 

ioctl(fd,FBIOGET_VSCREENINFO,&fbinfo);

printf("x:%d y:%d bit_per_pixel:%d\n",fbinfo.xres,fbinfo.yres,fbinfo.bits_per_pixel);

plcd = mmap(

NULL ,//表示映射的地址,为空让系统自动分配

fbinfo.xres*fbinfo.yres*fbinfo.bits_per_pixel/8,//分配内存的大小

PROT_WRITE,//对这个内存区域访问的权限

MAP_SHARED,//其他进程访问的权限

fd,

0//偏移量

);

if(plcd == MAP_FAILED)

{

perror("mmap fail");

close(fd);

return -1;

}

int x,y;

struct pichead *head=creathead();//创建单链表;

head=dirsize(argv[1],head);//把图片文件名加到链表里面去;

printklink(head);//打印图片;

munmap(plcd,fbinfo.xres*fbinfo.yres*fbinfo.bits_per_pixel/8);//解映射;

close(fd);

return 0;

}

 

 

 

 

 

//功能;能实现通过左右滑动实现图片切换;

#include<stdio.h>

#include<sys/types.h>

#include<dirent.h>

#include<sys/stat.h>

#include<unistd.h>

#include<string.h>

#include<stdlib.h>

#include<fcntl.h>

#include<sys/ioctl.h>

#include<linux/fb.h>

#include<sys/mman.h>

#include<jpeglib.h>

#include<setjmp.h>

#include<linux/input.h>

int fd;

int *plcd=NULL;

void bmp_display(char *pathname);

void jpeg_display(char *pathname);

 

struct picnode//定义结点结构体

{

char name[32];

struct picnode *pre;

struct picnode *next;

int mode;

};

struct pichead//定义头节点结构体,里面没有内容

{

struct picnode *next;

struct picnode *pre;

 

};

struct pichead *creathead()//创建头节点

{

struct pichead *dhead=(struct pichead *)malloc(sizeof(*dhead));

dhead->next=NULL;

dhead->pre=NULL;

return dhead;

 

}

void addnode(struct pichead *head,struct picnode *p)//将结点一个一个加入到链表里面,注意头

//节点的pre和最后一个结点的next为NULL;

{

 

if(head==NULL||p==NULL)

{

return;

}

if(head->next==NULL)

{

head->next=p;

head->pre=p;

}

else

{

head->pre->next=p;

p->pre=head->pre;

head->pre=p;

}

}

struct picnode *printklink(struct picnode *p,int ff)

{

 

if(ff==1)//ff为1时,显示左滑的照片;

{

p=p->pre;

printf("%s %d\n",p->name,p->mode);

if(p->mode==1)

{

jpeg_display(p->name);

}

else if(p->mode==0)

{

bmp_display(p->name);

}

}

else if(ff==0)//为0时显示向右的照片;

{

p=p->next;

 

printf("%s %d\n",p->name,p->mode);

if(p->mode==1)

{

jpeg_display(p->name);

}

else if(p->mode==0)

{

bmp_display(p->name);

}

}

 

 

return p;

 

}

 

struct pichead * dirsize(char *pathname,struct pichead *head)//把图片路径都搜索出来

//放入链表的name里面

{

 

DIR *dir;

dir=opendir(pathname);

struct stat st;

char filename[520];

int size=0;

if(dir==NULL)

{

perror("open dir fail");

}

struct dirent *dirp=NULL;

while(dirp=readdir(dir))//while循环不断读取目录里面的内容;

{

 

if(strcmp(dirp->d_name,".")==0||strcmp(dirp->d_name,"..")==0)

{

continue;

}

sprintf(filename,"%s/%s",pathname,dirp->d_name);

if(strcmp(filename+strlen(filename)-4,".jpg")==0)//筛选.jpg格式照片;

{

struct picnode *p=(struct picnode *)malloc(sizeof(*p));

strcpy(p->name,filename);

p->mode=1;

p->next=NULL;

p->pre=NULL;

addnode(head,p);

}

if(strcmp(filename+strlen(filename)-4,".bmp")==0)//筛选.bmp格式照片;

{

 

struct picnode *p=(struct picnode *)malloc(sizeof(*p));

strcpy(p->name,filename);

p->mode=0;

p->next=NULL;

p->pre=NULL;

addnode(head,p);

 

 

}

 

 

stat(filename,&st);

if(S_ISDIR(st.st_mode))//如果是目录,继续调用函数遍历;

{

dirsize(filename,head);

}

 

 

}

closedir(dir);

return head;

}

 

 

 

 

void LCD_Draw_Point(int x,int y,int color)//画点函数

{

if(x >=0 && x < 800 && y >=0 && y < 480)

{

*(plcd + 800*y + x) = color;

}

}

void bmp_display(char *pathname)//bmp格式图片显示

{

int fdBmp;

int w,h;

unsigned char buf[4];

int color_depth;

 

//打开对应的文件

fdBmp = open(pathname,O_RDONLY);

if(fdBmp<0)

{

perror("bmp open fail");

return;

}

//判断是不是BMP图片

read(fdBmp,buf,2);

if(buf[0] != 0x42  || buf[1] != 0x4d)

{

printf("This is not a BMP picture\n");

return;

}

//读图片的宽度

lseek(fdBmp,0x12,SEEK_SET);

read(fdBmp,buf,4);

w = buf[3] << 24 | buf[2] << 16 | buf[1] << 8 | buf[0];

//读图片的高度

lseek(fdBmp,0x16,SEEK_SET);

read(fdBmp,buf,4);

h = buf[3] << 24 | buf[2] << 16 | buf[1] << 8 | buf[0];

 

printf("w=%d h=%d\n",w,h);

 

//读图片的色深

lseek(fdBmp,0x1c,SEEK_SET);

read(fdBmp,buf,2);

color_depth = buf[1] << 8 | buf[0];

 

//计算图片数据的大小

int size = abs(w*h*color_depth/8) ;

 

//分配用来保存图片数据的内存空间

unsigned char *pixel = malloc(size);

lseek(fdBmp,54,SEEK_SET);

read(fdBmp,pixel,size);

 

int x,y;

int i=0;

unsigned char a,r,g,b;

int color;

 

for(y=0;y < abs(h); y++)

{

for(x=0;x<abs(w);x++){

b = pixel[i++];

g = pixel[i++];

r = pixel[i++];

a = (color_depth == 32) ? pixel[i++] : 0;

color = a << 24 | r << 16 | g << 8 | b; //组合成一个新的颜色值ARGB

int dy = h > 0 ? (h - 1 - y) : y; //判断图片是从左下角还是左上角开始显示

LCD_Draw_Point(x,dy,color);

}

}

free(pixel);

close(fdBmp);

}

 

void jpeg_display(char *pathname)//jpeg图片显示函数

{

 

 

//1)、分配并且初始化一个jpeg的解压对象

 

struct jpeg_decompress_struct cinfo;  //jpeg解压对象

struct jpeg_error_mgr jerr; //jpeg解压出错处理的结构体

cinfo.err = jpeg_std_error(&jerr); //初始化这两个对象

jpeg_create_decompress(&cinfo);

 

//2)、将需要解压的JPEG图片读进来

 

 

FILE * infile;

if ((infile = fopen(pathname, "r")) == NULL) {

    fprintf(stderr, "can't open \n");

    exit(1);

}

jpeg_stdio_src(&cinfo, infile);

 

//3)、读取JPEG的头信息

jpeg_read_header(&cinfo, TRUE);

 

//4)、设置解压的参数,如果不需要修改,就不需要做什么,采用默认的解压参数就可以了。

 

//5)、调用对应的函数,进行解压操作

//printf("cinfo.output_components=%d cinfo.output_height=%d\n",cinfo.output_components,cinfo.output_height);

jpeg_start_decompress(&cinfo);

printf(" cinfo.output_height=%d\n",cinfo.output_height);

printf("components=%d width=%d\n",cinfo.output_components,cinfo.output_width);

 

unsigned char *buffer = malloc(cinfo.output_width * cinfo.output_components);

 

//6)、逐行读入JPEG的数据,并且解压

int x,y=0;

while ( cinfo.output_scanline < cinfo.output_height )

{

y=cinfo.output_scanline;

jpeg_read_scanlines(&cinfo, &buffer, 1);

 

unsigned char a,r,g,b;

int color;

unsigned char *p = buffer;

for(x=0;x < cinfo.output_width;x++)

{

if(cinfo.output_components == 3)

{

a=0;   //如果cinfo.output_components == 3 它只有RGB的值

}

else

{

a=*p++; //否则是ARGB的格式

}

r = *p++;

g = *p++;

b = *p++;

color = a << 24 | r << 16 | g << 8 | b;

if(y<480 && x < 800)

{

LCD_Draw_Point(  x, y, color);

}

}

 

}

 

//7)、调用函数完成解压操作

jpeg_finish_decompress(&cinfo);

 

//8)、释放JPEG解压对象

jpeg_destroy_decompress(&cinfo);

fclose(infile);

 

 

 

 

}

int main(int argc,char *argv[])

{

fd = open("/dev/fb0",O_RDWR);//打开framebuffer,相当于显存;

if(fd < 0)

{

perror("open lcd fail");

return -1;

}

struct fb_var_screeninfo fbinfo;

 

ioctl(fd,FBIOGET_VSCREENINFO,&fbinfo);

printf("x:%d y:%d bit_per_pixel:%d\n",fbinfo.xres,fbinfo.yres,fbinfo.bits_per_pixel);

 

plcd = mmap(

NULL ,//表示映射的地址,为空让系统自动分配

fbinfo.xres*fbinfo.yres*fbinfo.bits_per_pixel/8,//分配内存的大小

PROT_WRITE,//对这个内存区域访问的权限

MAP_SHARED,//其他进程访问的权限

fd,

0//偏移量

);

if(plcd == MAP_FAILED)

{

perror("mmap fail");

close(fd);

return -1;

}

int x,y;

for(y=0;y<480;y++)

{

for(x=0;x<800;x++)

{

*(plcd + x + y*800) = 0x000000FF;//显示蓝色屏幕;

}

}

 

struct pichead * head=creathead();

head=dirsize(argv[1],head);

struct picnode *p=head->next;

 

 

if(p->mode==1)

{

jpeg_display(p->name);

}

else if(p->mode==0)

{

bmp_display(p->name);

}//创建头结点,并显示头节点下一节点的图片,因为头节点没内荣;

 

 

 

int fdts;

struct input_event ts;//事件结构体;

 

fdts = open("/dev/input/event0",O_RDONLY);

if(fdts < 0)

{

perror("ts open fail");

return -1;

}

while(1)

{

int m1=0,m2=0,flag=0;

while(1)

{

read(fdts,&ts,sizeof(struct input_event));

if(ts.type == EV_KEY && ts.code == 0x14a )//按键事件,只有在按下时值为1,滑动过程没值,值为触摸屏事件;

{

if(ts.value==1)//按下

{

flag=1;//标志位;

 

}

else if(ts.value==0)//松开

{

if(m1>m2)

{

if(p->pre==NULL)

{

p=head->pre;

}//因为头节点pre为空

p=printklink(p,1);

break;//左滑;

}

else if(m1<m2)

{

if(p->next==NULL)

{

p=head->next;

}//最后一个节点的next为NULL;

p=printklink(p,0);

break;//右滑;

}

}

}

else if(ts.type == EV_ABS&&ts.code == ABS_X)//采集两点的x坐标;

{

if (flag==1)

{

m1=ts.value;

flag=2;

}

else if(flag==2)

{

m2=ts.value;

}

}

 

}

}

mummap(plcd,fbinfo.xres*fbinfo.yres*fbinfo.bits_per_pixel/8);//解映射;

close(fdts);

close(fd);

return 0;

}

 

//功能:实现左右点切换图片

#include <stdio.h>

#include <fcntl.h>

#include <linux/input.h>

#include <sys/ioctl.h>

#include <linux/fb.h>

#include <sys/mman.h>

#include <stdlib.h>

#include <jpeglib.h>

int fd;

int *plcd=NULL;

void LCD_Draw_Point(int x,int y,int color)

{

if(x >=0 && x < 800 && y >=0 && y < 480)

{

*(plcd + 800*y + x) = color;

}

}

void jpeg_display(char *pathname)

{

 

 

//1)、分配并且初始化一个jpeg的解压对象

 

struct jpeg_decompress_struct cinfo;  //jpeg解压对象

struct jpeg_error_mgr jerr; //jpeg解压出错处理的结构体

cinfo.err = jpeg_std_error(&jerr); //初始化这两个对象

jpeg_create_decompress(&cinfo);

 

//2)、将需要解压的JPEG图片读进来

 

 

FILE * infile;

if ((infile = fopen(pathname, "r")) == NULL) {

    fprintf(stderr, "can't open \n");

    exit(1);

}

jpeg_stdio_src(&cinfo, infile);

 

//3)、读取JPEG的头信息

jpeg_read_header(&cinfo, TRUE);

 

//4)、设置解压的参数,如果不需要修改,就不需要做什么,采用默认的解压参数就可以了。

 

//5)、调用对应的函数,进行解压操作

//printf("cinfo.output_components=%d cinfo.output_height=%d\n",cinfo.output_components,cinfo.output_height);

jpeg_start_decompress(&cinfo);

printf(" cinfo.output_height=%d\n",cinfo.output_height);

printf("components=%d width=%d\n",cinfo.output_components,cinfo.output_width);

 

unsigned char *buffer = malloc(cinfo.output_width * cinfo.output_components);

 

//6)、逐行读入JPEG的数据,并且解压

int x,y=0;

while ( cinfo.output_scanline < cinfo.output_height )

{

y=cinfo.output_scanline;

jpeg_read_scanlines(&cinfo, &buffer, 1);

 

unsigned char a,r,g,b;

int color;

unsigned char *p = buffer;

for(x=0;x < cinfo.output_width;x++)

{

if(cinfo.output_components == 3)

{

a=0;   //如果cinfo.output_components == 3 它只有RGB的值

}

else

{

a=*p++; //否则是ARGB的格式

}

r = *p++;

g = *p++;

b = *p++;

color = a << 24 | r << 16 | g << 8 | b;

if(y<480 && x < 800)

{

LCD_Draw_Point(  x, y, color);

}

}

 

}

 

//7)、调用函数完成解压操作

jpeg_finish_decompress(&cinfo);

 

//8)、释放JPEG解压对象

jpeg_destroy_decompress(&cinfo);

fclose(infile);

}

int main()

{

fd = open("/dev/fb0",O_RDWR);

if(fd < 0)

{

perror("open lcd fail");

return -1;

}

struct fb_var_screeninfo fbinfo;

ioctl(fd,FBIOGET_VSCREENINFO,&fbinfo);

printf("x:%d y:%d bit_per_pixel:%d\n",fbinfo.xres,fbinfo.yres,fbinfo.bits_per_pixel);

plcd = mmap(

NULL ,//表示映射的地址,为空让系统自动分配

fbinfo.xres*fbinfo.yres*fbinfo.bits_per_pixel/8,//分配内存的大小

PROT_WRITE,//对这个内存区域访问的权限

MAP_SHARED,//其他进程访问的权限

fd,

0//偏移量

);

if(plcd == MAP_FAILED)

{

perror("mmap fail");

close(fd);

return -1;

}

int x,y;

for(y=0;y<480;y++)

{

for(x=0;x<800;x++)

{

*(plcd + x + y*800) = 0x000000FF;

}

}

int fdts;

struct input_event ts;

 

fdts = open("/dev/input/event0",O_RDONLY);

if(fdts < 0)

{

perror("ts open fail");

return -1;

}

 

while(1)

{

read(fdts,&ts,sizeof(struct input_event));

if(ts.type == EV_ABS)

{

if(ts.code == ABS_X)

{

 

printf("x=%d\n",ts.value);

if(ts.value<=400)

{

jpeg_display("caobo/1.jpg");

}

else

{

jpeg_display("caobo/2.jpg");

 

}

 

}

else if(ts.code == ABS_Y)

{

printf("y=%d\n",ts.value);

}

}

 

}

 

close(fdts);

 

return 0;

}

 

 

 

 

 

 

 

 

 

 

 

 

 

猜你喜欢

转载自blog.csdn.net/weixin_41723504/article/details/81430770