基于Linux的简易电子相册制作

本人是一名双非一本自动化专业在读大三学生,因学习过程总是冗长乏味,故想把自己所学一字一句记录下来,由于尚在入门阶段,与周围大佬差距甚大,有所不足之处,欢迎指正批评。

该项目是在Ubuntu/C语言环境下,通过运行一块虚拟的 800*400*4 的LCD屏幕,首先利用mmap内存映射简化文件访问和处理过程,通过内存指针在内存中访问文件内容,进行读取或写入操作。

void init_lcd()
{
		//1. 打开LCD设备文件
		int fd = open("/dev/ubuntu_lcd", O_RDWR);
		if(fd == -1)
		{
			perror("open");
			return ;
		}
		//2. 映射
		plcd = mmap(NULL, 800*480*4, PROT_READ|PROT_WRITE, MAP_SHARED,	 fd, 0);
}

该项目显示图片格式仅支持bmp图片,通过函数实现读取bmp文件信息(文件宽  高  深度  像素数组大小)并且做出打印在LCD屏幕的操作。

//显示 像素数组
void draw_image(int x0,int y0,int width, int height , const unsigned char image[])
{
	int i,j,k=0;
	int color;
	for(i=height;i>=0;i--)
	for(j=0;j<width;j++)
	{
		color = image[k]|(image[k+1]<<8)|(image[k+2]<<16);
		k = k+3;
		draw_point(j+x0, i+y0, color);
	}
}
//读"1.bmp" 文件,获取 w,h,depth
int draw_bmp(int x0,int y0, const char *bmpfile)
{
	unsigned char buf[4];
	
	int fd = open(bmpfile,O_RDONLY);
	if(fd < 0)
	{
		perror("open");
		return -1;
	}
	read(fd, buf, 2);
	if(buf[0]=='B' && buf[1]=='M')
	{
		printf("It's bmpfile\n");
	}
	else 
		return -1;
	//1. 读出文件的 宽,高,色深:才能知道像素数组的大小
	lseek(fd, 0x12,SEEK_SET);
	read(fd, buf, 4);//宽为4字节
	int width = (buf[3]<<24)|(buf[2]<<16)|(buf[1]<<8)|buf[0];
	//2. 读出文件的 高
	lseek(fd, 0x16,SEEK_SET);
	read(fd, buf, 4);
	int height = (buf[3]<<24)|(buf[2]<<16)|(buf[1]<<8)|buf[0];
	//3. 读出文件的 色深
	lseek(fd, 0x1c,SEEK_SET);
	read(fd, buf, 2);
	int depth = (buf[1]<<8)|buf[0];  //24
	// 4:像素数组大小: width * height *depth/8
	// 读 像素数组
	unsigned char *image = (unsigned char*)malloc(width * height *depth/8);
	lseek(fd, 54, SEEK_SET); // bmp 信息head占了 54个字节
	read(fd, image, width * height *depth/8);
	draw_image(x0,y0, width, height, image);
	
}

为了实现简易人机交互,我添加了触摸屏模块,利用函数实现,用于从触摸屏设备 /dev/ubuntu_event 中读取触摸事件的坐标信息,并返回一个包含 x 和 y 坐标的结构体 pos

//读取触摸屏信息函数

struct pos getPos()
{
	struct pos p;
	p.x = -1;
	p.y = -1;
	int fd = open("/dev/ubuntu_event", O_RDONLY);
	if(fd < 0)
	{
		perror("open");
		return p;
	}
	// 读触摸屏驱动文件:可以读到一个 事件的结构体  
	struct input_event ev;
	while(1)
	{
		read(fd, &ev, sizeof(ev));
		//printf("type=%d, code=%d, value=%d\n", ev.type, ev.code, ev.value);
		if(ev.type==3 && ev.code==0)
		{
			//printf("x = %d ", ev.value);
			p.x = ev.value;
		}
		else if(ev.type==3 && ev.code==1)
		{
			//printf("y = %d\n", ev.value);
			p.y = ev.value;
			close(fd);
			return p;
		}
				
	}
}

随后进入项目核心部分通过链表尾插法将要显示的图片储存起来,当按下LCD屏幕指定区域后,利用单向循环链表实现显示下一张图片、返回上一张图片的功能,此外,我利用fork创建一个子进程,在子进程中实现播放音乐(也可使用线程实现)。部分主循环函数代码如下:

  p = getPos();
        printf("x = %d, y = %d\n", p.x, p.y);
        
        if (p.x > 0 && p.x <= 100 && p.y > 0 && p.y < 480)
		{
            if (head != NULL && current_node != NULL)
				{
                struct Node* prev_node = NULL;
                struct Node* temp_node = head;
                while (temp_node && temp_node->next != current_node)
				{
                    temp_node = temp_node->next;
                }
                prev_node = temp_node;

                if (prev_node != NULL) 
				{
                    current_node = prev_node;
                } 
				else
				{
                   	struct Node* temp_node = head;
  					 while (temp_node->next != NULL)
					{
      					 temp_node = temp_node->next;
    				}
   						 current_node = temp_node;
                }
                displayImage(current_node);
            }
        } 
			else if (p.x >= 700 && p.x < 800 && p.y > 0 && p.y < 480)
			{
            	if (current_node != NULL && current_node->next != NULL)
				{
                current_node = current_node->next;
           		} 
			else
			{
                current_node = head;
            }
            displayImage(current_node);
        	}



			pid_t pid = fork();
            if (pid == 0) 
			{                 // 子进程
               if (system("madplay mp3/duvet.mp3") == -1) 
				{
       				 perror("system");
				}
                exit(0);
            }
        if (p.x >= 750 && p.y >= 0 && p.y <= 50) 
		{
            // 释放内存
            struct Node* temp;
            while (head != NULL)
			{
                temp = head;
                head = head->next;
                free(temp);
            }
            break;
        }

具体实现的视频如下:

ubuntu简易电子相册

📢写在最后

博主只是一名想从事嵌入式linux开发的小白,创作不易,之后还会不定时分享我学习的项目经验。

  • 🎉感谢关注🎉
  • 17
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
嵌入式Linux电子相册是一款基于嵌入式Linux操作系统开发的电子相册软件,用于在嵌入式设备上展示照片和图片。 嵌入式Linux电子相册具有以下特点和功能: 1. 轻量级:嵌入式Linux操作系统通常采用轻量级的内核和系统组件,使得电子相册软件在资源占用方面更加节省,能够在资源有限的嵌入式设备上运行。 2. 图片浏览:电子相册软件可以方便地浏览设备中的照片和图片,通过图形界面展示照片的缩略图,并支持放大、缩小、旋转、浏览等操作,让用户可以轻松查看和管理照片。 3. 幻灯片播放:电子相册软件支持幻灯片播放模式,可以设置图片切换的时间和效果,自动播放设备中的照片,将照片以流畅的动画形式展示给用户。 4. 多媒体支持:电子相册软件能够支持不同格式的图片文件,包括常见的JPG、PNG等,以及动态图片格式如GIF。同时,它还可以支持音乐的播放,用户可以通过设置背景音乐为相册添加更多的氛围。 5. 传输和存储:电子相册软件支持通过USB、蓝牙等接口将照片从其他设备传输到嵌入式设备上,也可以将照片保存到SD卡或其他存储媒体中进行备份,方便用户的照片管理和存储。 嵌入式Linux电子相册通过其简洁的界面和丰富的功能,使得用户可以在嵌入式设备上完美展示自己的照片收藏,无论是家庭相册、旅行照片,还是艺术作品,都可以通过这款软件得到优雅的展示和呈现。温馨提示:电子相册软件的具体功能和界面可能因开发者和设备而有所不同,以上仅供参考描述。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值