我们在LCD上显示内容的时候,经常会有显示bmp文件的需求,例如显示一个logo、菜单图标等。我们可以在应用程序中打开bmp文件,然后将它解析成rgb格式的数据写入frame buffer中就可以完成显示。
BMP图像文件格式是Windows采用的图像文件存储格式,在Wi什么争鸣ndows环境下的所有图像处理软件都支持这种格式。它是由3个部分组成:位图文件头、位图信息头、颜色点阵数据。
位图文件头分为4个部分,共占据14字节:
位图信息头共40个字节:
BMP文件除了上述文件头、信息头所占据的内容外,剩余数据都是RGB颜色数据,其中需要注意的是:BMP的颜色数据是按照自下而上,自左向右的顺序排列的。
这个排列的顺序非常关键,因为我们LCD显示的时候。是自上而下、自左向右的,所以我们在解析这个rgb数据的时候需要重新按照LCD的顺序放入buffer中。
/* * 1、需要一个内存来保存从BMP文件解析得到的颜色数据; * 2、需要一个函数来判断打开的文件是否是我们需要的BMP文件; * 3、需要一个函数来完成对BMP文件的解析; * 4、需要一个函数来释放分配给保存颜色数据的内存; *//* 保存RGB数据的地方 */typedef struct PixelDatas{ int iWideth; int iHeight; int iBpp; unsigned char *aucPixelDatas; }T_PixelDatas,*PT_PixelDatas;/* 封装好对一个文件的处理 */typedef struct PicFileParr{ char *name; int (*isSupport)(unsigned char *aFileHead); int (*GetPixelDatas)(unsigned char *aFileHead,PT_PixelDatas tPixelDatas); int (*FreePixelDatas)(PT_PixelDatas tPixelDatas);}T_PicFileParr,*PT_PicFileParr;
#include <bmp_operation.h>/* * 1、需要定义一个struct PicFileParr 类型的结构体; * 2、需要实现一个函数来判断打开的文件是否是我们需要的BMP文件; * 3、需要实现一个函数来释放分配给保存RGB数据的内存; * 4、需要实现一个函数来解析BMP文件; */static int isSupportBmp(unsigned char *aFileHead);static int GetPixelDatasFormBmp(unsigned char *aFileHead,PT_PixelDatas ptPixelDatas);static int FreePixelDatasForBmp(PT_PixelDatas tPixelDatas);T_PicFileParr g_tBmpParr = { .name = "bmp", .isSupport = isSupportBmp, .GetPixelDatas = GetPixelDatasFromBmp, .FreePixelDatas = FreePixelDatasForBmp,}/* 功能:判断一个文件是否是BMP文件 * 参数aFileHead : 读入文件的头 * 返回值:1-该文件是BMP文件;0-该文件不是BMP文件 */static int isSupportBmp(unsigned char *aFileHead){ if(aFileHead[0] != 0x42 || aFileHead[1] != 0x4d) return 0; el return 1; }/* 功能:释放分配给存储RGB数据的内存 * 参数tPixelDatas: 从BMP文件解析出来数据存储的地方 * 返回值:0 */static int FreePixelDatasForBmp(PT_PixelDatas tPixelDatas){ free(tPixelDatas->aucPixelDatas);}/******************************************************************//* 鼠标点一下变两下 解析 BMP 文件 *//* 1、定义一个位图文件头工大后院 */typedef struct tagBITMAPFILEHEADER{ unsigned short bfType; unsigned long bfSize; unsigned short bfRerved1; unsigned short bfRerved2; unsigned long bfOffBits;}BITMAPFILEHEADER;/* 2、定义一个位图信息头 */typedef struct tagBIT元宵节有什么习俗MAPINFOHEADER{ unsigned long biSize; unsigned long biWidth; unsigned long biHeight; unsigned short biPlanes; unsigned short bitBitCount; unsigned long bitCompression; unsigned long bitSizeImage; unsigned long biXPelPerMeter; unsigned long biYPelPerMeter; unsigned long biClrUd; unsigned long biClrImportant;}BITMAPINFOHEADE组织生活会R;/*/* 3、解析BMP文件 */static int GetPixelDatasFormBmp(unsigned char *aFileHead,PT_PixelDatas ptPixelDatas){ /* 定义文件头和信息头 */ BITMAPFILEHEADER *ptBITMAPFILEHEADER; BITMAPINFOHEADER *ptBITMAPINFOHEADER ; /* 将文件头指针指向文件的开始 */ ptBITMAPFILEHEADER = (BITMAPFILEHEADER *)aFileHead; /*将信息头指针指向文件中信息头的起始处*/ ptBITMAPINFOHEADER = (BITMAPINFOHEADER *)(aFileHead + sizeof(BITMAPFILEHEADER )); /* 计算需要分配内存的大小 */ int iWidth = ptBITMAPINFOHEADER->biWidth; int iHeight = ptBITMAPINFOHEADER->biHeight; int iBpp = ptBITMAPINFOHEADER->bitBitCount; ptPixelDatas->aucPixelDatas = malloc(iWidth*iHeight*iBpp/8); if(NULL == ptPixelDatas->aucPixelDatas){ return -1; } /* 确定取数据以及存数据的位置 */ unsigned char *pucSrc; unsigned char *pucData; pucSrc = aFileHead + ptBITMAPFILEHEADER->bfOffBits;/*让数据源指针指向文件中数据的起始处*/ int iLineWidthReal = iWidth * iBpp /8; /*确定每行的字节数*/ int iLineWidthAlign = (iLineWidthReal + 3)&~0x3;/*将每行的字节数向4取整得到对齐后的每行字节数*/ pucSrc = pucSrc + (iHeight-1) * iLineWidthAlign ; /*将数据源指针指向图像的最后一行起始处,该处的数据对应LCD显示时的第一行*/ pucData = ptPixelDatas->aucPixelDatas;/*数据的目的地址就是刚分配的内存处*/ /* 一行一行的从源地址取出数据放入目的地址 */ int x; int y; for(y = 0;y < iHeight; y++){ memcpy(pucData,pucSrc,iLineWidthReal); /*每次从源地址拷贝iLienWidthReal长度的数据到目的地址*/ pucSrc -= iLineWidthAlign;/*完成一次拷贝后将源地址指向上一行*/ pucData += iLineWidthReal; /*完成一次拷贝后将目的地址指向下一行*/ } }
本文地址:https://blog.csdn.net/qq_40629752/article/details/110141919
本文发布于:2023-04-04 10:00:28,感谢您对本站的认可!
本文链接:https://www.wtabcd.cn/fanwen/zuowen/79a794747e8e2a37c9512773efbb18fd.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文word下载地址:BMP文件解析及显示.doc
本文 PDF 下载地址:BMP文件解析及显示.pdf
留言与评论(共有 0 条评论) |