【Liux下6818开发板(ARM)】实现简易相册

news2024/11/17 4:44:32
  • (꒪ꇴ꒪ ),hello我是祐言
  • 博客主页:C语言基础,Linux基础,软件配置领域博主🌍
  • 快上🚘,一起学习!
  • 送给读者的一句鸡汤🤔:
  • 集中起来的意志可以击穿顽石!
  • 作者水平很有限,如果发现错误,可在评论区指正,感谢🙏

 一、基本流程

        这个程序实现了一个实现简易的相册,使用6818开发板的液晶屏和触摸屏,可以显示多张BMP格式的图片,并支持通过触摸屏的操作切换图片。

        程序的主要功能和流程如下:

  1. 打开液晶屏设备文件,并将液晶屏映射到内存:通过打开/dev/fb0设备文件,并使用mmap函数将液晶屏映射到内存,以便后续在屏幕上显示图片。

  2. 打开触摸屏设备文件:通过打开/dev/input/event0设备文件,实现对触摸屏输入事件的捕获和处理。

  3. 获取图片路径名字:通过get_bmpname函数获取指定目录下的所有BMP格式图片的路径名字,并存储在数组bmppath中。

  4. 显示第一张图片:程序默认显示第一张图片,使用show_bmp函数将图片显示在液晶屏上。

  5. 循环监听触摸事件:进入无限循环,程序不断监听触摸屏的输入事件。根据触摸坐标判断用户点击了屏幕的哪个区域。

  6. 切换图片:根据触摸坐标的位置,如果用户点击了右上角区域,则切换到上一张图片;如果点击了右下角区域,则切换到下一张图片。通过更新bmppath数组的索引 来实现图片的切换,并调用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;
}

        全部的文件打包放这了。

模拟相册icon-default.png?t=N6B9https://download.csdn.net/download/qq_64928278/88136955?spm=1001.2014.3001.5501

        更多C语言Linux系统相关文章,关注专栏:

   手撕C语言

            玩转linux

📢写在最后

  • 今天的分享就到这啦~
  • 觉得博主写的还不错的烦劳 一键三连喔~
  • 🎉感谢关注🎉

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/816959.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Linux NameSpace 虚拟化 资源隔离

NameSpace NameSpace介绍 在操作系统中命名空间命名空间提供的是系统资源的隔离&#xff0c;其中系统资源包括了&#xff1a;进程、网络、文件系统等等 实际上linux系统实现命名空间主要目的之一就是为了实现轻量级虚拟化服务&#xff0c;也就是我们说的容器&#xff0c;在同…

分享一个赛车动画

先看效果&#xff08;动画太大了放不上来&#xff0c;甘心去复制代码运行即可&#xff09;&#xff1a; 再看代码&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>赛车</title><…

AD21 PCB设计的高级应用(六)极坐标的应用

&#xff08;六&#xff09;极坐标的应用 在 PCB 设计过程中,特别是 LED圆形灯板的 PCB 设计,需要对 LED灯珠进行圆形等间距排列,如果每个元件都计算清楚其坐标再进行放置会非常烦琐。要实现如图 所示的元件布局效果,在 Altium Designer 软件里可以使用极坐标的方法。 (1)打开…

Vue2 第十一节 Vue的生命周期

1.生命周期的概念 2.生命周期流程图 3.生命周期分析 一.生命周期概念 生命周期又称为生命周期回调函数&#xff0c;生命周期函数&#xff0c;生命周期钩子是Vue在关键时刻帮我们调用的一些特殊名称的函数生命周期函数的名字不可更改&#xff0c;但函数的具体内容是程序员根…

【低代码开发】:加速应用开发的未来趋势

低代码开发&#xff1a;加速应用开发的未来趋势 引言什么是低代码以及功能特点&#xff1f;什么是低代码开发&#xff1f;低代码平台的特点和功能低代码平台的应用场景和优势低代码的优点低代码的缺点低代码平台项目开发流程选择和实施低代码平台 低代码未来的发展趋势低代码平…

MyBatis缓存-提高检索效率的利器--一级缓存

&#x1f600;前言 本篇博文是关于MyBatis一级缓存的介绍使用和缓存失效情况分析&#xff0c;希望能够帮助到您&#x1f60a; &#x1f3e0;个人主页&#xff1a;晨犀主页 &#x1f9d1;个人简介&#xff1a;大家好&#xff0c;我是晨犀&#xff0c;希望我的文章可以帮助到大家…

c++基础知识(inline、auto、nullptr)

⭐️ 内联函数 &#x1f4ac; 为什么会有内联函数&#xff1f;   内联函数其实是为了弥补 c 的缺陷&#xff0c;比如当我们遇到了一些少量逻辑和代码的情况时&#xff0c;而这些少量的代码又需要被重复使用多次&#xff08;swap&#xff09;&#xff0c;我们往往会封装成为一…

linux快速安装tomcat

linux快速安装tomcat 前提安装好jdk 下载Tomcat安装包 wget https://dlcdn.apache.org/tomcat/tomcat-10/v10.0.27/bin/apache-tomcat-10.0.27.tar.gz如果出现颁发的证书已经过期的错误提示,用下面命令 wget --no-check-certificate https://dlcdn.apache.org/tomcat/tomcat-1…

剑指 Offer 第二版

剑指 Offer 第二版 文章目录 剑指 Offer 第二版[剑指 Offer 06. 从尾到头打印链表](https://www.nowcoder.com/practice/d0267f7f55b3412ba93bd35cfa8e8035?tpId13&tqId23278&ru/exam/oj/ta&qru/ta/coding-interviews/question-ranking&sourceUrl%2Fexam%2Foj…

区块链实验室(13) - 在PBFT中节点的度与其流量的特征

前面若干实验说明了PBFT的耗时、流量与度的特征&#xff0c;见 区块链实验室(10) - 实例说明PBFT的共识过程, 区块链实验室(11) - PBFT耗时与流量特征, 区块链实验室(12) - 网络拓扑对PBFT共识流量的影响 同样的实验方案&#xff0c;在100个节点构成的无标度网络中完成100次交…

html学习4(区块、布局)

1、<div> 是块级元素&#xff0c;它独占一行&#xff0c;可以设置宽度、高度以及边距等样式属性。它适合用于创建页面的大块结构&#xff0c;例如页面的主体区域、容器、布局等。 2、<span> 是行内元素&#xff0c;它不会独占一行&#xff0c;宽度默认由其内容决定…

Ubuntu20.04安装Autoware.universe并与Awsim联调

文章目录 引言一、安装依赖1.1 安装git1.2 克隆Autoware到本地1.3 自动安装相关依赖1.4 安装显卡驱动1.5 安装ROS2 Galactic1.6 安装ros2_dev_tools1.7 安装rmw_implementation1.8 安装pacmod1.9 安装autoware_core1.10 安装autoware universe dependencies1.11 安装pre_commit…

(2)Gymnasium--CartPole的测试

1、主要参考 &#xff08;1&#xff09; CartPole 强化学习详解1 - DQN_Oxalate-c的博客-CSDN博客 &#xff08;2&#xff09;官方文档&#xff0c;推荐&#xff01;&#xff01;&#xff01;&#xff01; Cart Pole - Gymnasium Documentation 2、相关说明 2.1 动作空间 …

DP-GAN-生成器代码

在train文件中&#xff0c;对生成器和判别器分别进行更新&#xff0c;根据loss的不同&#xff0c;分别计算对于的损失&#xff1a; loss_G, losses_G_list model(image, label, "losses_G", losses_computer)loss_D, losses_D_list model(image, label, "los…

环形链表 II(JS)

环形链表 II 题目 给定一个链表的头节点 head &#xff0c;返回链表开始入环的第一个节点。 如果链表无环&#xff0c;则返回 null。 如果链表中有某个节点&#xff0c;可以通过连续跟踪 next 指针再次到达&#xff0c;则链表中存在环。 为了表示给定链表中的环&#xff0c;…

企业数字化转型失败率达80%,面临哪些挑战?应该如何规划?

随着数字化在社会的飞速发展&#xff0c;人们的生活工作娱乐等方方面面都已经被数字化占领&#xff0c;数字化所衍生出的数字经济更是成为高速增长的国民经济支柱&#xff0c;而数据作为“副产品”也成功进化为第五大生产要素&#xff0c;发挥出巨大的价值&#xff0c;变成了个…

智慧展馆展厅人员定位系统解决方案:提升参观体验与管理效率

随着数字化时代的到来&#xff0c;展馆和展厅逐渐成为人们了解文化、艺术、科技等领域的重要窗口。 然而&#xff0c;传统的展馆和展厅存在着一些问题&#xff0c;例如参观者迷路、信息获取不及时、管理效率低下等。 为了提升参观体验和管理效率&#xff0c;研发智慧展馆展厅…

测试|Selenium之WebDriver常见API使用

测试|Selenium之WebDriver常见API使用 文章目录 测试|Selenium之WebDriver常见API使用1.定位对象&#xff08;findElement&#xff09;css定位xpath定位css选择器语法&#xff1a;xpath语法:校验结果 2.操作对象鼠标点击对象在对象上模拟按键输入clear清除对象输入的文本内容su…

TCP三次握手和四次挥手以及11种状态(一)

1、三次握手 置位概念&#xff1a;根据TCP的包头字段&#xff0c;存在3个重要的标识ACK、SYN、FIN ACK&#xff1a;表示验证字段 SYN&#xff1a;位数置1&#xff0c;表示建立TCP连接 FIN&#xff1a;位数置1&#xff0c;表示断开TCP连接 三次握手过程说明&#xff1a; 1、…

【自动化剧本】Role角色

目录 一、Roles模块1.1roles的目录结构1.2roles 内各目录含义解释1.3在一个 playbook 中使用 roles 的步骤 二、使用Role编写LNMP剧本2.1 搭建Nginx角色2.2搭建Mysql角色2.3搭建php角色2.4lnmp剧本 一、Roles模块 roles用于层次性、结构化地组织playbook。roles能够根据层次型结…