gec6818_液晶屏显示bmp图片

图片属性:

        bmp24位

        自由分辨率(小于等于屏幕800*480)

24位bmp格式图片的编码特点:
         1.每个像素点占3个字节存放的BGR数据  B蓝色  G绿色  R红色。
         2.编码方式是上下颠倒。
         3.最前面有54字节的头信息  。

         4.bmp图片的宽度占用的字节数如果不能被4整除,

            window系统会给每一行填充垃圾数凑  够4字节整除。

步骤:
        1.打开图片,打开液晶屏,,获取图片宽和高,映射得到液晶屏再内存中首地址

        2.判断宽度(width)是否能被4整除,根据判断结果读取图片颜色值

        3.按位于转换得到的图片颜色值。(液晶屏显示是每个像素4个字节ARGB,

           而bmp每个像素3个字节BGR)

        4.把读取的字节上下颠倒写入到液晶屏中

 实现代码如下:

#include "myhead.h"
int main(int argc,char **argv)
{
	int bmpfd;
	int lcdfd;
	//定义指针保存液晶屏的首地址
	int *lcdmem;
	int i;
	int x,y;
	int width;
	int height;

	//打开图片,打开液晶屏
	bmpfd=open(argv[1],O_RDWR);
	if(bmpfd==-1)
	{
		perror("打开图片失败!\n");
		return -1;
	}
	lcdfd=open("/dev/fb0",O_RDWR);
	if(lcdfd==-1)
	{
		perror("打开液晶屏失败!\n");
		return -1;
	}
	
	//获取图片的宽和高
	lseek(bmpfd,18,SEEK_SET);
	read(bmpfd,&width,4);
	read(bmpfd,&height,4);
	printf("w:%d,h:%d\n",width,height);
	
	//定义数组存放读取到一张bmp图片的颜色值
	char bmpbuf[width*height*3];
	//定义数组存放转换得到的ARGB数据
	int lcdbuf[width*height];  //int类型占4个字节
	
	//映射得到液晶屏在内存中首地址
	lcdmem=mmap(NULL,800*480*4,PROT_READ|PROT_WRITE,MAP_SHARED,lcdfd,0);
	if(lcdmem==NULL)
	{
		perror("映射液晶屏失败了!\n");
		return -1;
	}
	//读取图片的颜色值
	/*
		由于bmp图片最前面54字节根本就不是颜色值,从55字节开始才是像素点的真实颜色值
	*/
	lseek(bmpfd,54,SEEK_SET);
	//从55字节开始读取
	
	
	//判断宽度是否能被4整除
	if(width%4==0){
		//被4整除,一下子读完
		read(bmpfd,bmpbuf,width*height*3);
	}else{
		//不被4整除,一行一行读
		//每行读到最后(width),设置当前往后偏移(宽%4的余数)
		for(i=0;i<height;i++){
			read(bmpfd,bmpbuf+i*width*3,width*3);
			lseek(bmpfd,width%4,SEEK_CUR);
		}
	}
	//把读取的颜色值写入到液晶屏中
	/*
		由于液晶屏要求每个像素点占4个字节,但是bmp图片每个像素点只有三个字节
		想办法让它们对齐
		bmpbuf[0]--》第一个像素点的B
		bmpbuf[1]--》第一个像素点的G
		bmpbuf[2]--》第一个像素点的R
		利用C语言位运算和左移配合(忘记请参见老师笔记)
		     0x00     --》A透明度
			 bmpbuf[2]--》R 
			 bmpbuf[1]--》G
             bmpbuf[0]--》B
		     0x00<<24|bmpbuf[2]<<16|bmpbuf[1]<<8|bmpbuf[0]
	*/
	for(i=0; i<width*height; i++)
		lcdbuf[i]=0x00<<24|bmpbuf[3*i+2]<<16|bmpbuf[3*i+1]<<8|bmpbuf[3*i];
	
	//清屏
	for(x=0; x<800; x++)
	{
		for(y=0; y<480; y++)   //*(p+i)  p[i]   *(lcdmem+偏移量)=颜色值   lcdmem[偏移量]=颜色值
			lcdmem[(479-y)*800+x]='\0';
	}
	//把颠倒的画面翻转过来
	for(i=0;i<height;i++){
		//一行一行复制到屏幕上,行数上下颠倒
		memcpy(lcdmem+800*i,&lcdbuf[width*(height-1-i)],width*4);
		lseek(bmpfd,(width*height)%4,SEEK_CUR);
	}
	//收尾
	close(bmpfd);
	close(lcdfd);
	munmap(lcdmem,800*480*4); //解除内存映射
	return 0;	
}

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值