- (꒪ꇴ꒪ ),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));
else
bzero(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
📢写在最后
- 今天的分享就到这啦~
- 觉得博主写的还不错的烦劳
一键三连喔
~ - 🎉感谢关注🎉