设计程序,实现在LCD上任意位置显示一张任意大小的色深为24bit的bmp图片,要求图像不失真可以在开发板的LCD上显示。
文件IO练习题
设计程序,实现在LCD上任意位置显示一张任意大小的色深为24bit的bmp图片,要求图像不失真可以在开发板的LCD上显示。
代码:
/*****************************************************************************************************************
*
* file name : ShowBmp.c
* author : [email protected]
* data : 2024/05/13
* function : 实现在LCD上任意位置显示一张任意大小的色深为24bit的bmp图片,不要越界
* note : None
*
* CopyRight (c) 2024 [email protected] 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;
}