设计程序,实现在LCD上任意位置显示一张任意大小的色深为24bit的bmp图片,要求图像不失真可以在开发板的LCD上显示。

文件IO练习题

设计程序,实现在LCD上任意位置显示一张任意大小的色深为24bit的bmp图片,要求图像不失真可以在开发板的LCD上显示。

代码:

/*****************************************************************************************************************
*	
*	file name	:	ShowBmp.c
*	author	 	:	cnzycwp@126.com
*	data  	 	:	2024/05/13
*	function	:	实现在LCD上任意位置显示一张任意大小的色深为24bit的bmp图片,不要越界
*	note	 	  :	None
* 	
*  	CopyRight (c)	2024	cnzycwp@126.com 	All Right Reseverd
*
* ****************************************************************************************************************/

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/mman.h>

#pragma pack(1)

// 定义BMP文件头部结构
typedef struct{
	unsigned short bfType;          //标识该文件为bmp文件,判断文件是否为bmp文件,即用该值与"0x4d42"比较是否相等即可,0x4d42 = 19778
	unsigned int   bfSize;          //位图文件大小,包括这14个字节。
	unsigned short bfReserved1;     //预保留位,暂不用。
	unsigned short bfReserved2;     //预保留位,暂不用。
	unsigned int   bfOffBits;       //图像数据区的起始位置
}BITMAPFILEHEADER;                  //文件头

typedef struct{
	unsigned int biSize;            //本结构的长度,为40个字节。
	int biWidth;				    //宽度
	int biHeight;				    //高度
	unsigned short biPlanes;        //目标设备的级别,必须是1。
	unsigned short biBitCount;	    //色深,每个像素所占的位数(bit),其值必须为1(黑白图像)、4(16色图)、8(256色)、24(真彩色图),新的BMP格式支持32位色。
	unsigned int biCompression;     //压缩方式,有效的值为BI_RGB(未经压缩)、BI_RLE8、BI_RLE4、BI_BITFILEDS(均为Windows定义常量)。
	unsigned int biSizeImage;       //图像区数据大小,即实际的位图数据占用的字节数
	int biXPelsPerMeter;            //水平分辨率,像素每米
	int biYPelsPerMeter;            //垂直分辨率,单位是像素/米
	unsigned int biClrUsed;         //位图实际用到的颜色数,如果该值为零,则用到的颜色数为2的biBitCount次幂。
	unsigned int biClrImportant;    //位图显示过程,重要的颜色数;0--所有都重要
}BITMAPINFOHEADER;     


#pragma pack()

void ShowBmp(char *name,int x1,int y1,int *lcd_mp)
{
	//1.打开待显示的BMP图像  fopen
	FILE * bmp_fp = fopen(name,"rb");
	if (NULL == bmp_fp)
	{
		return -1;
	}

	//2.读取BMP文件的图像信息,获取BMP的宽和高
	BITMAPINFOHEADER headerinfo;
	BITMAPFILEHEADER headerfile;
	fseek(bmp_fp,sizeof(headerfile),SEEK_SET);
	fread(&headerinfo,1,sizeof(headerinfo),bmp_fp); //读取40字节
	printf("bmp width = %d,height = %d\n",headerinfo.biWidth,headerinfo.biHeight);

	//3.读取BMP图*片的颜色分量  800*480*3
	char *bmp_buf = calloc(1,headerinfo.biWidth*headerinfo.biHeight*(headerinfo.biBitCount/8));
	fread(bmp_buf,1,headerinfo.biWidth*headerinfo.biHeight*(headerinfo.biBitCount/8),bmp_fp);

	//4.关闭BMP
	fclose(bmp_fp);

	//5.打开LCD   open  
	int lcd_fd = open(lcd_mp,O_RDWR);


	//6.对LCD进行内存映射  mmap
	lcd_mp = (int *)mmap(NULL,800*480*4,PROT_READ|PROT_WRITE,MAP_SHARED,lcd_fd,0);

	//7.循环的把BMP图像的颜色分量依次写入到LCD的像素点中 
	int i = 0;
	int data = 0;

	for (int y = y1+headerinfo.biHeight-1; y >= y1; y--)
	{
		for (int x = x1; x < x1+headerinfo.biWidth ; ++x)
		{
			//把BMP图片的一个像素点的颜色分量转换为LCD屏幕的一个像素点的颜色分量格式  ARGB <--- BGR
			data |= bmp_buf[i];			//B
			data |= bmp_buf[i+1]<<8;	//G
			data |= bmp_buf[i+2]<<16;  	//R

			lcd_mp[800 * y + x] = data;  //BGR BGR BGR .... 

			i+=3;  
			data = 0;
		}
	}
	
	//8.关闭LCD
	close(lcd_fd);
	munmap(lcd_mp,800*480*4);
}


int main(int argc, char const *argv[])
{
	int x,y;
	//1.用户输入任意位置的坐标
  	printf("please input your x and y coordinate:");
  	scanf("%d %d",&x,&y);


	ShowBmp(argv[1],x,y,"/dev/fb0");
	return 0;
}
posted @ 2024-05-13 21:48  陳文鹏  阅读(63)  评论(0编辑  收藏  举报