粤嵌gec6818开发板显示bmp图片

        前段时间做了一个项目,用到了linux环境下gec6818开发板显示bmp文件,在这里给大家分享一下。

        要在LCD上显示bmp图片首先要打开lcd文件

/*LCD文件*/
    lcd_fd = open("/dev/fb0", O_RDWR);
    if (lcd_fd < 0)
    {
        printf("打开LCD文件失败\n");
        return -1;
    }
    printf("LCD文件初始化完毕\n");

        如果用直接写rgb值的方法回导致屏幕刷新特别慢,所以这里使用的是内存映射的方法

/*内存映射*/
    FB = (int *)mmap(NULL, 800*480*4, PROT_READ | PROT_WRITE, MAP_SHARED,lcd_fd, 0);
    printf("内存映射完毕\n");

        然后是调用bmp显示函数,这里用两个函数分别显示全屏图片和任意大小图片

/*
	功能:显示800*480大小的bmp图片。
	参数:
		char *pathname:要显示图片的名字。
		int *show_1152000bmp_fd:被映射区的指针。
	返回值:成功  0
			失败  -1
*/
int show_1152000bmp(char *pathname, int *show_1152000bmp_fd)
{
	//1、打开BMP格式图片和lcd显示屏
	int fd_bmp = open(pathname,  O_RDWR);
	if(fd_bmp == -1)
	{
		printf("show_1152000bmp(), open bmp fail!\n");
		return -1;
	}
	
	//2、去掉54个字节
	int ret = lseek(fd_bmp, 54, SEEK_SET);
	if(ret == -1)
	{
		printf("show_1152000bmp(), lseek bmp fail!\n");
		return -1;		
	}
	
	//3、读取BMP数据到lcd屏幕中
	char bmp_buf[800*480*3];
	int lcd_buf[800*480];
	bzero(bmp_buf, 800*480*3);
	bzero(lcd_buf, 800*480);
	
	ret = read(fd_bmp, bmp_buf, 800*480*3);//BMP数据放到了bmp_buf中
	if(ret == -1)
	{
		printf("show_1152000bmp(), read bmp fail!\n");
		return -1;		
	}		

	//4、关闭文件,回收资源
	close(fd_bmp);
	
	//5、800*480个A像素变成800*480个B像素算法。
	int i;
	for(i=0; i<800*480; i++)
	{
		lcd_buf[i] = bmp_buf[i*3]<<0 | bmp_buf[i*3+1]<<8 | bmp_buf[i*3+2]<<16;
		//lcd_buf[0] = bmp_buf[0]<<0 | bmp_buf[1]<<8 | bmp_buf[2]<<16;
		//lcd_buf[1] = bmp_buf[3]<<0 | bmp_buf[4]<<8 | bmp_buf[5]<<16;
		//lcd_buf[2] = bmp_buf[6]<<0 | bmp_buf[7]<<8 | bmp_buf[8]<<16;
	}
	
	//6、lcd_buf数据(DDR2中的数据)通过mmap显示到LCD屏幕中。
/*
	for(i=0; i<800*480; i++)
	{
		*(lcd_mmap+i)=lcd_buf[i];
	}	
*/
	int x, y;
	for(y=0; y<480; y++)//优化算法,解决图片颠倒问题
	{
		for(x=0; x<800; x++)
		{
			*(show_1152000bmp_fd+800*(479-y)+x)= lcd_buf[800*y+x];
		}
	}
			
	return 0;
}

/*
	功能:(不超过800*480显示屏大小)显示任意位置任意大小的bmp图片
	形参:
		char *pathname:要显示图片的名字
		int lcd_x_coordinates:lcd屏的x轴坐标
		int lcd_y_coordinates:lcd屏的y轴坐标(通过x、y轴坐标确定显示图片起始显示坐标)	
		int wide:所显示图片的宽度
		int height:所显示图片的高度
		int *show_bmp_lcd_mmap:被映射区的指针
	返回值:成功  0
			失败  -1
	
*/
int show_location_bmp(char *pathname,int lcd_x_coordinates, int lcd_y_coordinates, int wide, int height,int *show_bmp_lcd_mmap) 
{
	int i;
	int ret;
	int x, y;
	
	char bmp_buf[wide*height*3];
	int  new_buf[wide*height];
	bzero(bmp_buf, sizeof(bmp_buf));
	bzero(new_buf, sizeof(new_buf));

	int bmp_fd = open(pathname, O_RDONLY);//1、打开BMP格式图片
	if(bmp_fd == -1)
	{
		printf("show_location_bmp(), open bmp failed\n");
		return -1;
	}

	ret = lseek(bmp_fd,54,SEEK_SET);//2、跳过bmp图片的前54个位置
	if(ret == -1)
	{
		printf("show_location_bmp(), lseek bmp failed\n");		
		return -1;
	}

    int *new_p = show_bmp_lcd_mmap + 800*lcd_y_coordinates + lcd_x_coordinates;//3、重新确定映射位置。
	
	ret = read(bmp_fd, bmp_buf, wide*height*3);//4、取读图片像素
	if(ret == -1)
	{
		printf("show_location_bmp(), read bmp failed\n");	
		return -1;
	}
	
	close(bmp_fd);//5、关闭图片
	
	for(i=0; i<wide*height; i++)//6、24bits 转 32bits控制变量
	{
			new_buf[i] = bmp_buf[i*3]<<0  |  bmp_buf[(i*3)+1]<<8 | bmp_buf[(i*3)+2]<<16;		
	}
	
	for(y=0;y<height;y++)//7、解决图片上下颠倒问题
	{
		for(x=0;x<wide;x++)
		{
			*(new_p+(800*((height-1)-y))+x) = new_buf[wide*y+x];
		}
	}
	
	return 0;		
}

        最后是解除内存映射,关闭lcd文件

/*解除内存映射*/
    munmap(FB, 800*480*4);
    printf("内存映射解除完毕\n");

    /*关闭LCD*/
    close(lcd_fd);
    printf("LCD关闭完毕\n");

        代码实测可用,下面再附上一些bmp图片的特效显示函数

/*
	功能:切换BMP图片特效“圆形扩散”。
	参数:
	char *pathname:图片的路径。
	int *pic_circular_spread_fd:被映射区的指针。
	返回值:成功  0
	失败  -1
*/
int pic_circular_spread(char *pathname, int* pic_circular_spread_fd)
{
	int ret=0;
	int line=0;
	int block=0;
	int i=0, j=0, k=0;
	int bmp_fd=0;
	
	char bmp_buf[480*800*3];
	int mi_buf[480*800];	
	int temp_buf[480*800];	
	bzero(mi_buf,sizeof(mi_buf));
	bzero(bmp_buf,sizeof(bmp_buf));
	bzero(temp_buf,sizeof(temp_buf));

	bmp_fd = open(pathname, O_RDONLY);//1、打开BMP格式图片
	if(bmp_fd == -1)
	{
		printf("pic_circular_spread(), open bmp failed\n");
		return -1;
	}

	ret = lseek(bmp_fd, 54 , SEEK_SET);//2、跳过bmp图片的前54个位置
	if(ret == -1)
	{
		perror("pic_circular_spread(), lseek bmp failed\n");		
		return -1;
	}

	ret = read(bmp_fd , bmp_buf , sizeof(bmp_buf)); //4、取读图片像素
	if(ret == -1)
	{
		printf("pic_circular_spread(), read bmp failed\n");	
		return -1;
	}
	
	close(bmp_fd);//5、关闭图片

	for(i=0, j=0 ; i<800*480 ; i++, j+=3)//6、24bits 转 32bits控制变量
	{
		temp_buf[i] = bmp_buf[j+2]<<16 | bmp_buf[j+1]<<8 | bmp_buf[j] ;
	}

	for(line=0 ; line <=480 ;line++)//7、解决图片上下颠倒问题
	{
		for(i=0; i<=800 ; i++)
		mi_buf[800*line + i] = temp_buf[ (479-line)*800 + i ];
	}

	for(k=0; k<467; k+=3)//8、特殊动画“圆形扩散”效果算法
	{
		for(i=0; i<480; i++)
		{
			for(j=0; j<800; j++)
			{
				if((j-400)*(j-400)+(i-240)*(i-240) <= k*k)
				{
					pic_circular_spread_fd[800*i+j] = mi_buf[800*i+j];					
				}
			}
		}
	} 

	return 0;
}

/*
	功能:切换BMP图片特效”圆形收缩“。
	参数:	
		char *pathname:图片的路径。
		int *pic_circular_shrink_fd:被映射区的指针。
	返回值:成功  0
			失败  -1		
*/
int pic_circular_shrink(char *pathname, int* pic_circular_shrink_fd)
{	
	int ret=0;
	int line=0;
	int block=0;
	int i=0, j=0, k=0;
	int bmp_fd=0;
	
	char bmp_buf[480*800*3];
	int mi_buf[480*800];	
	int temp_buf[480*800];	
	bzero(mi_buf,sizeof(mi_buf));
	bzero(bmp_buf,sizeof(bmp_buf));
	bzero(temp_buf,sizeof(temp_buf));

	bmp_fd = open(pathname , O_RDONLY);//1、打开BMP格式图片
	if(bmp_fd == -1)
	{
		printf("pic_circular_shrink(), open bmp failed\n");
		return -1;
	}

	ret = lseek(bmp_fd, 54 , SEEK_SET);//2、跳过bmp图片的前54个位置
	if(ret == -1)
	{
		perror("pic_circular_shrink(), lseek bmp failed\n");		
		return -1;
	}

	ret = read(bmp_fd , bmp_buf , sizeof(bmp_buf)); //4、取读图片像素
	if(ret == -1)
	{
		printf("pic_circular_shrink(), read bmp failed\n");	
		return -1;
	}
	
	close(bmp_fd);//5、关闭图片

	for(i=0, j=0 ; i<800*480 ; i++, j+=3)//6、24bits 转 32bits控制变量
	{
		temp_buf[i] = bmp_buf[j+2]<<16 | bmp_buf[j+1]<<8 | bmp_buf[j] ;
	}

	for(line=0 ; line <=480 ;line++)//7、解决图片上下颠倒问题
	{
		for(i=0; i<=800 ; i++)
		mi_buf[800*line + i] = temp_buf[ (479-line)*800 + i ];
	}

	//8、特殊动画“圆形收缩”效果算法
	for(k=468; k>=0; k-=3)
	{
		for(i=0; i<480; i++)
		{
			for(j=0; j<800; j++)
			{
				if((j-400)*(j-400)+(i-240)*(i-240) >= k*k)
					pic_circular_shrink_fd[800*i+j] = mi_buf[800*i+j];
			}
		}
	}	
		
	return 0;
}

/*
	功能:切换BMP图片特效”向下飞入“。
	参数:
		char *pathname:图片的路径。
		int *pic_down_fd:被映射区的指针。
	返回值:成功  0
			失败  -1		
*/
int pic_down(char *pathname, int* pic_down_fd)
{	
	int ret=0;
	int line=0;
	int block=0;
	int i=0, j=0, k=0;
	int bmp_fd=0;
	
	char bmp_buf[480*800*3];
	int mi_buf[480*800];	
	int temp_buf[480*800];	
	bzero(mi_buf,sizeof(mi_buf));
	bzero(bmp_buf,sizeof(bmp_buf));
	bzero(temp_buf,sizeof(temp_buf));

	bmp_fd = open(pathname , O_RDONLY);//1、打开BMP格式图片
	if(bmp_fd == -1)
	{
		printf("pic_down(), open bmp failed\n");
		return -1;
	}

	ret = lseek(bmp_fd, 54 , SEEK_SET);//2、跳过bmp图片的前54个位置
	if(ret == -1)
	{
		perror("pic_down(), lseek bmp failed\n");		
		return -1;
	}

	ret = read(bmp_fd , bmp_buf , sizeof(bmp_buf)); //4、取读图片像素
	if(ret == -1)
	{
		printf("pic_down(), read bmp failed\n");	
		return -1;
	}
	
	close(bmp_fd);//5、关闭图片

	for(i=0, j=0 ; i<800*480 ; i++, j+=3)//6、24bits 转 32bits控制变量
	{
		temp_buf[i] = bmp_buf[j+2]<<16 | bmp_buf[j+1]<<8 | bmp_buf[j] ;
	}

	for(line=0 ; line <=480 ;line++)//7、解决图片上下颠倒问题
	{
		for(i=0; i<=800 ; i++)
		mi_buf[800*line + i] = temp_buf[ (479-line)*800 + i ];
	}

	//8、特殊动画“向下飞入”效果算法
	for(i=0; i<480; i++)
	{
		for(j=0; j<800; j++)
		{
			pic_down_fd[800*i+j] = mi_buf[800*i+j];	
		}
		usleep(1000);
	} 	

	return 0;
}

/*
	功能:切换BMP图片特效”向上飞入“。
	参数:
		char *pathname:图片的路径。
		int *pic_up_fd:被映射区的指针。
	返回值:成功  0
			失败  -1
*/
int pic_up(char *pathname, int* pic_up_fd)
{	
	int ret=0;
	int line=0;
	int block=0;
	int i=0, j=0, k=0;
	int bmp_fd=0;
	
	char bmp_buf[480*800*3];
	int mi_buf[480*800];	
	int temp_buf[480*800];	
	bzero(mi_buf,sizeof(mi_buf));
	bzero(bmp_buf,sizeof(bmp_buf));
	bzero(temp_buf,sizeof(temp_buf));

	bmp_fd = open(pathname , O_RDONLY);//1、打开BMP格式图片
	if(bmp_fd == -1)
	{
		printf("pic_up(), open bmp failed\n");
		return -1;
	}

	ret = lseek(bmp_fd, 54 , SEEK_SET);//2、跳过bmp图片的前54个位置
	if(ret == -1)
	{
		perror("pic_up(), lseek bmp failed\n");		
		return -1;
	}

	ret = read(bmp_fd , bmp_buf , sizeof(bmp_buf)); //4、取读图片像素
	if(ret == -1)
	{
		printf("pic_up(), read bmp failed\n");	
		return -1;
	}
	
	close(bmp_fd);//5、关闭图片

	for(i=0, j=0 ; i<800*480 ; i++, j+=3)//6、24bits 转 32bits控制变量
	{
		temp_buf[i] = bmp_buf[j+2]<<16 | bmp_buf[j+1]<<8 | bmp_buf[j] ;
	}

	for(line=0 ; line <=480 ;line++)//7、解决图片上下颠倒问题
	{
		for(i=0; i<=800 ; i++)
		mi_buf[800*line + i] = temp_buf[ (479-line)*800 + i ];
	}

	//8、特殊动画“向上飞入”效果算法
	for(i=479; i>=0; i--)
	{
		for(j=0; j<800; j++)
		{
			pic_up_fd[800*i+j] = mi_buf[800*i+j];	
		}
		usleep(500);
	} 	
	
	return 0;
}

        我最近建了一个嵌入式的QQ交流群,感兴趣的可以进群了解一下,我会在群里分享一些常用的代码封装,以及一些项目的源码。QQ群讨论也是完全开放,只要不打广告大家可以就嵌入式尽情的沟通和交流,大家对文章中的内容有疑问也可以在群中提出,有空会尽我所能给大家一些帮助。QQ群号:643408467

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值