BMP图片在开发板上的显示原函数(供参考)

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <unistd.h>
#include <sys/mman.h>
#include <string.h>
#include <sys/types.h>
#include <dirent.h>
#include <linux/input.h>
#include <time.h>
// #include "head4animation.h"    自定义用来实现切换图片效果的文件

//BMP文件头(14字节)
struct bitmap_header
{
    	int16_t type;// 位图文件的类型,必须为BM(1-2字节)
    	int32_t size;// 位图文件的大小,以字节为单位(3-6字节)
    	int16_t reserved1;// 位图文件保留字,必须为0(7-8字节)
    	int16_t reserved2;// 位图文件保留字,必须为0(9-10字节)
    	int32_t offbits;// 位图数据的起始位置,以相对于位图(11-14字节)
                     // 文件头的偏移量表示,以字节为单位
}__attribute__((packed));

//位图信息头(40字节)
struct bitmap_info
{
	int32_t size;// 本结构所占用字节数(15-18字节)	
	int32_t width;// 位图的宽度,以像素为单位(19-22字节)
	int32_t height;// 位图的高度,以像素为单位(23-26字节)
	int16_t planes;// 目标设备的级别,必须为1(27-28字节)

	int16_t bit_count;// 每个像素所需的位数,必须是1(双色),(29-30字节)
						// 4(16色),8(256色)或24(真彩色)之一
	int32_t compression;// 位图压缩类型,必须是 0(不压缩),(31-34字节)
						// 1(BI_RLE8压缩类型)或2(BI_RLE4压缩类型)之一
	int32_t size_img;// 位图的大小,以字节为单位(35-38字节)
	int32_t X_pel;// 位图水平分辨率,每米像素数(39-42字节)
	int32_t Y_pel;// 位图垂直分辨率,每米像素数(43-46字节)
	int32_t clrused;// 位图实际使用的颜色表中的颜色数(47-50字节)
	int32_t clrImportant;// 位图显示过程中重要的颜色数(51-54字节)
}__attribute__((packed));

int n;//图片个数
char pic[20][20];//存放所有为bmp图片的文件

void found_bmp(char  const *file_name);
void display_pic();
int  next_pic(int *x1);
int p= 0,v =0;


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


	 	found_bmp(argv[1]);
	 	display_pic();
	 
	return 0;
}




// 找到所有bmp类型的图片放在数组中
void found_bmp(char const *file_name)
{
	DIR *dp = opendir(file_name);
	
	if (dp == NULL)
	{
		return ;
	}
	struct dirent *d;
	int i = 0;

	while(d = readdir(dp))
	{
		if (!strcmp(d->d_name, ".") || !strcmp(d->d_name, ".."))
		{
			continue;
		}
		if (d == NULL)
		{
			break;
		}

		sprintf(pic[i],"%s/%s",file_name,d->d_name);
		printf("%s ",pic[i]);
		i++;
		n++;

	}
	closedir(dp);
}

void display_pic()
{
	//打开液晶屏幕文件
	int lcd_fd = open("/dev/fb0", O_RDWR);
	if (lcd_fd == -1)
	{
		perror("open pm");
		return ;
	}


	//(1)申请内存映射
	int *FB = mmap(NULL, 800*480*4, PROT_WRITE|PROT_READ, MAP_SHARED, lcd_fd, 0);
	// 利用循环 并显示
	int k = 0;
	unsigned long (*buf)[800] = calloc(800*480,4);


	// int x=0,y=0;
	while(1)
	{	
		// 打开图片文件
		int bmp_fd = open(pic[k], O_RDONLY);
		if (bmp_fd == -1)
		{
			perror("open bmp");
		}
		//读取文件头	
		struct bitmap_header bh;
		struct bitmap_info bi;
		read(bmp_fd, &bh, sizeof(bh));
		read(bmp_fd, &bi, sizeof(bi));
		printf("\n读取到第%d张--->w = %d, h = %d, bit = %d\n", k,bi.width, bi.height, bi.bit_count);

		//将RGB数据读出来
		char RGB[800*480*3];

		read(bmp_fd, &RGB, 800*480*3);

		//将RGB转成ARGB
		unsigned int ARGB[800*480];
		for (int i = 0; i < 800*480; ++i)
		{
			ARGB[i] = RGB[i*3+0]<<0|RGB[i*3+1]<<8|RGB[i*3+2]<<16;
		}
	    //y坐标翻转

	    for (int x = 0; x < 800; ++x)
	    {
		   for (int y = 0; y < 480; ++y)
		   {
			   buf[y][x] = ARGB[(479-y)*800+x];
		   }
	    }
	    //用内存映射方式显示
		if (FB == MAP_FAILED)
		{
			perror("mmap");
			return ;
		}


		while(v == p)
		{
			srand(time(NULL));
			v = rand()%4;
			printf("我在寻早不同的值\n");
		}
		p = v;//确保不重复
		switch(v)
		{
			case 0:printf("----0----"); falling_down_in(lcd_fd, buf); break;
			case 1:printf("----1----"); floating_up_in(lcd_fd, buf);  break;
			case 2:printf("----2----"); left2right_in(lcd_fd, buf);   break;
			case 3:printf("----3----"); right2left_in(lcd_fd, buf);   break;
		}
		
		int t;//接收x
		int f = next_pic(&t);//接收y
		printf("坐标x1 = %d\n", t);
		printf("坐标y1 = %d\n", f);
		if (t >950 && f< 50)
		{
			printf("返回到第一张\n");
			printf("-----------------坐标x1------------%d\n", t);
			printf("-----------------坐标y1------------%d\n", f);
			k = 0;		
			continue;
		}
		if (t<50 && f<50)
		{
			printf("返回到最后一张\n");
			printf("-----------------坐标x1------------%d\n", t);
			printf("-----------------坐标y1------------%d\n", f);
			k = n-1;
			continue;
		}
		if (t > 980 && f> 570)
		{
			printf("结束放映\n");
			printf("-----------------坐标x1------------%d\n", t);
			printf("-----------------坐标y1------------%d\n", f);
			break ;
		}
		if (t>512)
		{
			k++;
			if (k == n)
			{
				k = 0;
			}
		}
		else
		{
			k--;
			if(k == -1)
			{
				k = n-1;
			}

		}
		// munmap(FB, 800*480*4);//不要释放内存映射
		close(bmp_fd);
		// close(lcd_fd);//不可以关闭屏幕资源

	}
	
}


int next_pic(int *x1)
{
	// 打开触摸屏
	int ts_fd = open("/dev/input/event0", O_RDONLY);//gec6818下的触摸屏文件
	if (ts_fd == -1)
	{
		perror("open");
		return 0;
	}
	struct input_event input_info;
	while(1)
	{
		//这里会产生阻塞
		read(ts_fd, &input_info, sizeof(input_info));
		switch(input_info.type)
		{
		case EV_SYN:printf("---------SYN-------\n");break;
		case EV_ABS://触摸屏事件
			switch(input_info.code)
			{
			case ABS_X: *x1= input_info.value;break;
			case ABS_Y: return input_info.value;
			// case ABS_PRESSURE:
			// 	printf("p = %d\n", input_info.value);return input_info.value;
			}
		default:break;
		}
	}
}


	

/* 该部分为显示效果的代码 如需实现请自行调用 或者重新创建一个c文件在调用
#include <linux/input.h>
#include "head4animation.h"
#include <unistd.h>

void floating_up_in(int lcd, unsigned long (*image)[WIDTH])
{ 
	unsigned long (*FB)[WIDTH] = mmap(NULL, SCREEN_SIZE * 4,
		PROT_READ | PROT_WRITE, MAP_SHARED, lcd, 0);  
	int i = 0; 
	while(1) 
	{ 
		memcpy(&FB[HEIGHT-i-1][0], &image[0][0], 
			WIDTH*4*(i+1)); 
		if(i >= HEIGHT-1) 
			break; 
		usleep(80);
		i++;
	} 
}
void right2left_in(int lcd, unsigned long (*image)[WIDTH]) 
{ 
	unsigned long (*FB)[WIDTH] = mmap(NULL, SCREEN_SIZE * 4,
	PROT_READ | PROT_WRITE, MAP_SHARED, lcd, 0); 
	int i, j; 
	for(i=0; i<WIDTH; i++)
	{ 
		for(j=0; j<HEIGHT; j++) 
		{ 
			memcpy(&FB[j][WIDTH-1-i], &image[j][0],4*(i+1));
		} 
			usleep(80); 
		} 
}

void left2right_in(int lcd, unsigned long (*image)[WIDTH]) 
{ 
	unsigned long (*FB)[WIDTH] = mmap(NULL, SCREEN_SIZE * 4,
	PROT_READ | PROT_WRITE, MAP_SHARED, lcd, 0); 
	int i, j; 
	for(i=0; i<WIDTH; i++)
	{ 
		for(j=0; j<HEIGHT; j++) 
		{ 
			memcpy(&FB[j][0], &image[j][WIDTH-1-i],4*(i+1));
		} 
			usleep(80); 
		} 
}
*/




















 

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值