- (꒪ꇴ꒪ ),hello我是祐言
- 博客主页:C语言基础,Linux基础,软件配置领域博主🌍
- 快上🚘,一起学习!
- 送给读者的一句鸡汤🤔:
- 集中起来的意志可以击穿顽石!
- 作者水平很有限,如果发现错误,可在评论区指正,感谢🙏
一、基本流程
这个程序实现了一个实现简易的相册,使用6818开发板的液晶屏和触摸屏,可以显示多张BMP格式的图片,并支持通过触摸屏的操作切换图片。
程序的主要功能和流程如下:
-
打开液晶屏设备文件,并将液晶屏映射到内存:通过打开
/dev/fb0
设备文件,并使用mmap
函数将液晶屏映射到内存,以便后续在屏幕上显示图片。 -
打开触摸屏设备文件:通过打开
/dev/input/event0
设备文件,实现对触摸屏输入事件的捕获和处理。 -
获取图片路径名字:通过
get_bmpname
函数获取指定目录下的所有BMP格式图片的路径名字,并存储在数组bmppath
中。 -
显示第一张图片:程序默认显示第一张图片,使用
show_bmp
函数将图片显示在液晶屏上。 -
循环监听触摸事件:进入无限循环,程序不断监听触摸屏的输入事件。根据触摸坐标判断用户点击了屏幕的哪个区域。
-
切换图片:根据触摸坐标的位置,如果用户点击了右上角区域,则切换到上一张图片;如果点击了右下角区域,则切换到下一张图片。通过更新
bmppath
数组的索引i
来实现图片的切换,并调用show_bmp
函数将新的图片显示在液晶屏上。
二、函数实现
主函数代码:
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <linux/input.h>
#include <time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <linux/fb.h>
#include <dirent.h>
#include <bmp.h>#define LCDDEV "/dev/fb0" #define PATH_SIZE 1024
#define PHOTO_SIZE 100#define TOUCH_DEV "/dev/input/event0" // 触摸屏设备文件路径void get_xy(int touch_fd,int *x,int *y)
{struct input_event buf;*x = -1;*y = -1;while (1){// 读取触摸事件int ret = read(touch_fd, &buf, sizeof(buf));if (ret == -1){perror("read fail");exit(errno);}// 判断事件类型是否是触摸事件if (buf.type == EV_ABS){// 根据事件类型设置对应的坐标值if (buf.code == ABS_X){*x = (buf.value * 800) / 1024;} if (buf.code == ABS_Y){*y = (buf.value * 800) / 1024;}}if (!(*x > 0 && *x < 800 && *y > 0 && *y < 480)){continue;} if(*x>-1 && *y>-1){break; // 得到坐标后退出} }}// 从目录中读取BMP类型图片路径名字
void get_bmpname(char *dir, char *bmppath[])
{char *cur_path = calloc(PATH_SIZE, sizeof(char)); //程序执行的位置char *dst_path = calloc(PATH_SIZE, sizeof(char)); //指定要读取文件的路径if( !(cur_path && dst_path) ){perror("calloc fail");exit(errno);}// 保留程序执行的位置getcwd(cur_path, PATH_SIZE);// 获取指定目录的绝对路径chdir(dir);getcwd(dst_path, PATH_SIZE);// 1.打开目录文件DIR *dp = opendir(dir);if ( dp == NULL ){perror("opendir fail");exit(errno);}// 2. 读取目录项int i = 0;struct dirent *ep = NULL;while(1){ep = readdir(dp);if ( ep == NULL && errno == 0 ) //成功读完所有的目录项{break;} else if( ep == NULL ) //进入到这个判断,说明errno值已被改变,出现某种错误{perror("readdir fail");}if ( strstr(ep->d_name, ".bmp") ){if(bmppath[i] == NULL)bmppath[i] = calloc(PATH_SIZE, sizeof(char));elsebzero(bmppath[i], PATH_SIZE);snprintf(bmppath[i], PATH_SIZE, "%s/%s", dst_path, ep->d_name);i++;}else{continue;}}// 继续向后检索,是否为NULL,不为空这次读取的图片资源没有上次多// 应该把多余申请的资源释放掉for(; bmppath[i] != NULL; i++){free(bmppath[i]);bmppath[i] = NULL;}// 关闭目录closedir(dp);
}int main(int argc, char *argv[])
{int x,y;// 打开液晶屏设备int lcd_fd = open(LCDDEV, O_RDWR);if(lcd_fd == -1){perror("open lcd fail");exit(errno);}// 给液晶屏文件映射一块内存int *fb = mmap(NULL, 800*480*4, PROT_READ|PROT_WRITE, MAP_SHARED, lcd_fd, 0);if(fb == MAP_FAILED){perror("mmap fail");exit(errno);}// 打开触摸屏int touch_fd = open(TOUCH_DEV, O_RDONLY);if (touch_fd < 0){perror("打开触摸屏失败");exit(errno);}// 获取指定目录的图片路径名字char *bmppath[PHOTO_SIZE] = {NULL};int i = 0;get_bmpname("./", bmppath);for (i=0; bmppath[i] != NULL; i++) //获取读到多少张图片路径/* empty */;//默认显示第一张图片 show_bmp(bmppath[0], fb, 0, 0);while(1) { get_xy(touch_fd, &x, &y);if(x>400 && x<800 && y>0 && y<240){ //右上角的那块区域{--i; if (i < 0){i = 5;} show_bmp(bmppath[i], fb, 0, 0);}} else if(x>400 && x<800 && y>240 && y<480){ //右下角的那块区域++i;if (i > 5) {i = 0; // 如果i小于0,跳转至6}show_bmp(bmppath[i], fb, 0, 0);}} // 关闭触摸屏close(touch_fd);// 关闭液晶屏munmap(fb, 800*480*4);close(lcd_fd);return 0;
}
全部的文件打包放这了。
模拟相册https://download.csdn.net/download/qq_64928278/88136955?spm=1001.2014.3001.5501
更多C语言和Linux系统相关文章,关注专栏:
手撕C语言
玩转linux
📢写在最后
- 今天的分享就到这啦~
- 觉得博主写的还不错的烦劳
一键三连喔
~ - 🎉感谢关注🎉