提供3000多款全球软件/控件产品
针对软件研发的各个阶段提供专业培训与技术咨询
根据客户需求提供定制化的软件开发服务
全球知名设计软件,显著提升设计质量
打造以经营为中心,实现生产过程透明化管理
帮助企业合理产能分配,提高资源利用率
快速打造数字化生产线,实现全流程追溯
生产过程精准追溯,满足企业合规要求
以六西格玛为理论基础,实现产品质量全数字化管理
通过大屏电子看板,实现车间透明化管理
对设备进行全生命周期管理,提高设备综合利用率
实现设备数据的实时采集与监控
利用数字化技术提升油气勘探的效率和成功率
钻井计划优化、实时监控和风险评估
提供业务洞察与决策支持实现数据驱动决策
转帖|其它|编辑:郝浩|2010-11-22 13:38:18.000|阅读 823 次
概述:Bmp文件是非常常用的位图文件,无论是游戏还是其他都被广泛使用。针对bmp文件的处理也有一堆现成的api进行调用,然而文件内部究竟怎样,如何自己来解析这样的文件呢?为了消除无聊,我用了几天时间来研究了一下,同时作为学习笔记,进行记录。
# 慧都年终大促·界面/图表报表/文档/IDE等千款热门软控件火热促销中 >>
Bmp文件是非常常用的位图文件,无论是游戏还是其他都被广泛使用。针对bmp文件的处理也有一堆现成的api进行调用,然而文件内部究竟怎样,如何自己来解析这样的文件呢?为了消除无聊,我用了几天时间来研究了一下,同时作为学习笔记,进行记录。
首先,整个bmp文件的内容可以分为3到4块。之所以分为3到4块而不是固定的值,是因为,对于bmp来说可能存在调色板或者一些掩码。具体稍候讨论。
第一块是bmp的文件头用于描述整个bmp文件的情况。结构如下:
typedef struct tagBITMAPFILEHEADER {
WORD bfType;
DWORD bfSize;
WORD bfReserved1;
WORD bfReserved2;
DWORD bfOffBits;
} BITMAPFILEHEADER, *PBITMAPFILEHEADER;
这些信息相当有用,如果你想直接来解析bmp文件。第一个bfType用于表示文件类型,如果它是bmp文件,那么它这个位置的值一定是"BM" 也就是0x4D42。第二个bfSize表示整个文件的字节数。第三第四个 则保留,目前无意义,最后一个相当重要,表示,位图的数据信息离文件头的偏移量,以字节为单位。
第二块是位图信息头,即BITMAPINFOHEADER,用于描述整个位图文件的情况。以下挑重要的数据进行解释
typedef struct tagBITMAPINFOHEADER{
DWORD biSize; //表示本结构的大小
LONG biWidth; //位图的宽度
LONG biHeight; //位图的高度
WORD biPlanes; //永远为1 ,由于没有用过所以 没做研究 附msdn解释
//Specifies the number of planes for the target device. This value must be set to 1.
WORD biBitCount;//位图的位数 分为1 4 8 16 24 32 本文没对1 4 进行研究
DWORD biCompression; //本以为压缩类型,但是却另外有作用,稍候解释
DWORD biSizeImage; //表示位图数据区域的大小以字节为单位
LONG biXPelsPerMeter;
LONG biYPelsPerMeter;
DWORD biClrUsed;
DWORD biClrImportant;
} BITMAPINFOHEADER, *PBITMAPINFOHEADER;
第三块就是调色板信息或者掩码部分,如果是8位位图 则存放调色板 ;16 与32位位图则存放RGB颜色的掩码,这些掩码以DWORD大小来存放。
最后一块就是位图的数据实体。
实验:准备一张编码格式为RGB565的位图文件,分辨率是320*240。然后用VS2005建立C++程序对文件进行读取和分析。
开始实验:
在Windows资源管理器中,把鼠标悬停在位图上方,可以看到系统提示的一些位图信息"尺寸:320×40 大小:151K"。这个是通过如下计算方式得到的:位图文件除去位图数据实体外的三个部分的大小在同一文件系统下都是一样的,都为14+46+2*3=66字节(自己可以查看这些结构体数据的详细定义然后自己验证),位图编码为RGB565,也就是说每个彩色像素点是用的2个字节表示,R/G/B三个分量分别用了5/6/5位表示,5+5+6为16,刚好是两个字节,所以位图数据实体大小为320*240*2/1024=150K,再加上前面的66字节,整个位图的大小就是150K到151K之间了,而根据Windows系统的磁盘分块存储原理(最后一块数据即使比单位存储块1K要小,也会占用一个1K的存储块),所以此文件实际占用的空间为151K。此位图的结构示意如下图:
用VS2005建立C++项目,使用如下的测试代码:
void ReadBmpDemo()
{
CFile hFile;
hFile.Open(L"recvBmpData565.bmp",CFile::modeRead);//以打开的形式读取文件
//*******************************************
//***------Step 1:读取文件信息头---------****
//*******************************************
BITMAPFILEHEADER *pFileHead = NULL; // 位图文件的头指针
DWORD dwFileHeadSize = sizeof(BITMAPFILEHEADER);// 位图文件的头区域大小
pFileHead=(BITMAPFILEHEADER*)malloc(dwFileHeadSize);//申请一片dwFileHeadSize字节大小的内存区
hFile.Read(pFileHead,dwFileHeadSize);//从图片的文件当前位置读取一片内容:文件信息头
//*******************************************
//***------Step 2:读取位图信息头---------****
//*******************************************
BITMAPINFOHEADER *pBmpInfoHeader=NULL;
DWORD dwBmpInfoHeadSize=sizeof(BITMAPINFOHEADER);
pBmpInfoHeader=(BITMAPINFOHEADER*)malloc(dwBmpInfoHeadSize);//位图信息头
hFile.Read(pBmpInfoHeader,dwBmpInfoHeadSize);//读入第二块数据块
pBmpInfoHeader->biCompression = BI_RGB;//RGB555格式---修改压缩信息
//*****************************************************
//***------Step 3:读取调色板信息或掩码部分---------****
//*****************************************************
RGBQUAD *pRgbQuad=NULL;
DWORD dwRgbQuadSize=3*sizeof(RGBQUAD);//本次实验的RGB565位图有三块掩码.
pRgbQuad=(RGBQUAD*)malloc(dwRgbQuadSize);
hFile.Read(pRgbQuad,dwRgbQuadSize);
//*****************************************************
//***------Step 4:读取位图的数据实体---------**********
//*****************************************************
BYTE *pBmpData=NULL;
//DWORD dwBmpDataSize=2*(pBmpInfoHeader->biWidth)*(pBmpInfoHeader->biHeight);//因为高度是负的,所以暂时不用此方法
DWORD dwBmpDataSize=(pFileHead->bfSize) - (pFileHead->bfOffBits);//文件头中的文件大小和数据实体偏移量之间的差
pBmpData=(BYTE*)malloc(dwBmpDataSize);//申请一片指定字节大小的内存区.
hFile.Read(pBmpData,dwBmpDataSize);
hFile.Close();
//**************************************************************
//***------Step 5:将RGB565的数据实体转成RGB555---------*********
//**************************************************************
//因为不涉及到本部分内容,所以没有实现
//*******************************************
//***------Step Final:释放动态内存区---------****
//*******************************************
free(pFileHead);
pFileHead=NULL;
free(pBmpInfoHeader);
pBmpInfoHeader=NULL;
free(pRgbQuad);
pRgbQuad=NULL;
free(pBmpData);
pBmpData=NULL;
}
将准备的位图文件素材放到此项目的根目录下。然后断点调试,看运行的中间结果。
位图文件头:从这里面了解到位图文件相关信息,文件类型为19778(即位图的文件类型编号:0x4D42),文件大小为153666,位图数据实体偏移文件头部66。
位图信息头:从这个数据我们可以看到这个位图的相关信息,图片宽度为320,高度为240(当biHeight>0的时候位图是倒置的,它小于0的时候正常),位图的像素存储长度是16位(也就是RGB565的编码方式单像素点占用的长度),图片压缩类型为3(用来指示位图的编码方式是RGB565还是RGB555的,详细介绍可以查看WahtIf写的那个文章"BMP文件结构的探索"中的示例代码),位图数据实体大小为153600。
位图的调色板或掩码部分:对于RGB565的位图,这里面是三个颜色分量的掩码,这个直接关系到此位图文件在Windows下的显示的效果。这三个数据在对位图进行颜色分量提取的时候有比较大的作用,在WahtIf写的那个文章"BMP文件结构的探索"中有示例代码。
位图文件的数据实体部分:这里面以字节为单位存储着位图的每个个像素点的色彩信息,也是位图文件中数据的主体部分。此部分的数据长度在位图信息头中可以得到。
总结:在了解了位图文件的存储结构后,后面对位图的一切操作和变换都是围绕着这些数据来进行的,到时候不会再看着一张数字图片而茫然不知所措了,而是可以根据自己的需求提取自己想要的信息了。
本站文章除注明转载外,均为本站原创或翻译。欢迎任何形式的转载,但请务必注明出处、不得修改原文相关链接,如果存在内容上的异议请邮件反馈至chenjj@pclwef.cn
文章转载自:博客园面对“数字中国”建设和中国制造2025战略实施的机遇期,中车信息公司紧跟时代的步伐,以“集约化、专业化、标准化、精益化、一体化、平台化”为工作目标,大力推进信息服务、工业软件等核心产品及业务的发展。在慧都3D解决方案的实施下,清软英泰建成了多模型来源的综合轻量化显示平台、实现文件不失真的百倍压缩比、针对模型中的大模型文件,在展示平台上进行流畅展示,提升工作效率,优化了使用体验。
本站的模型资源均免费下载,登录后即可下载。模型仅供学习交流,勿做商业用途。
本站的模型资源均免费下载,登录后即可下载。模型仅供学习交流,勿做商业用途。
本站的模型资源均免费下载,登录后即可下载。模型仅供学习交流,勿做商业用途。
服务电话
重庆/ 023-68661681
华东/ 13452821722
华南/ 18100878085
华北/ 17347785263
客户支持
技术支持咨询服务
服务热线:400-700-1020
邮箱:sales@pclwef.cn
关注我们
地址 : 重庆市九龙坡区火炬大道69号6幢