【寒江雪】BMP位图文件格式分析
来源:互联网 发布:简述算法的复杂度分析 编辑:程序博客网 时间:2024/05/01 00:58
BMP位图文件格式分析
今天实验课主要要做BMP格式的文件解析。参照着学姐(长)的代码,将BMP文件按二进制格
式读到内存中。
所用的图片是一张25*25的全白色图片,由于背景图也为白色,就不上图了
首先对位图做一个解释
BMP文件格式
BMP文件格式由文件头,位图信息段,调色板信息(如果有的话),位图数据RGB像素或索引数据组成
由此,可以知道位图文件的代码可以这么表示:
typedef struct tagBITMAP_FILE { BITMAPFILEHEADER bitmapheader; BITMAPINFOHEADER bitmapinfoheader; PALETTEENTRY palette[256]; UCHAR *buffer; //UCHAR 大小1字节(同BYTE), 在VC6下} BITMAP_FILE;
BMP文件头:BITMAPFILEHEADER bitmapheader
typedef struct tagBITMAPFILEHEADER { WORD bfType; DWORD bfSize; WORD bfReserved1; WORD bfReserved2; DWORD bfOffBits; } BITMAPFILEHEADER;
- bfType:表明文件类型,位图文件设置为”BM”,占用一个字的存储空间
- bfSize:表明文件大小,占用两个字的存储空间
- bfReserved1:保留字,占用一个字的存储空间
- bfReserved2:保留字,占用一个字的存储空间
- bfOffBits:从文件头位置到图像数据位置的偏移量。占用两个字的存储空间
文件头的大小总共7个字,共14字节
以下是我那张25*25纯白色的图的详细信息以及通过程序解析得到的数据
- 其中42 4d是文件类型,查阅ASCII表可得到BM
- 00 00 07 a2表明文件大小为1954字节
- 00 00 00 00是两个保留字
- 00 00 00 36是偏移量,大小为54字节(我数了一下,文件头开始偏移54字节,刚好到第一个ff的位置)
位图信息段
typedef struct tagBITMAPINFOHEADER { // bmih DWORD biSize; LONG biWidth; LONG biHeight; WORD biPlanes; WORD biBitCount; DWORD biCompression; DWORD biSizeImage; LONG biXPelsPerMeter; LONG biYPelsPerMeter; DWORD biClrUsed; DWORD biClrImportant;} BITMAPINFOHEADER;
- biSize:说明BITMAPINFOHEADER所需要的字节数。占用2个字
- biWidth:说明图像的宽度。占用2个字
- biHeight:说明图像的高度。占用2个字
- biPlanes:表示BMP图像的平面属性。由于显示器只有一个平面,顾恒等于1。占用1个字
- biBitCount:说明比特数,其值位1/4/8/16/24或32。占用1个字
- biCompression:说明图像数据压缩的类型。占用2个字
- BI_RGB:没有压缩
- BI_RLE8:每个象素8比特的RLE压缩编码,压缩格式由2字节组成(重复像素和颜色索引)
- BI_RLE4:每个象素4比特的RLE压缩编码,压缩格式由2字节组成
- BI_BITFIELDS:每个象素的比特由指定的掩码决定。
- BI_JPEG:JPEG格式
- biSizeImage:说明图像的大小,以字节为单位。当用BI_RGB格式时,可设置为0。占用2个字
- biXPelsPerMeter:说明水平分辨率,用像素/米表示。占用2个字
- biYPelsPerMeter:说明竖直分辨率,用像素/米表示。占用2个字
- biClrUsed:说明位图实际使用的彩色表中的颜色索引数(设为0的话,则说明使用所有调色板项)。占用2个字
- biClrImportant:说明对图象显示有重要影响的颜色索引的数目,如果是0,表示都重要。占用2个字
总共使用20个字,共40字节。
到目前为止,文件头和位图信息总共使用了14+40=54字节。因此文件首部到图像数据位置总共偏移了54字节
以下是我那张白色25*25的图片的位图信息
- biSize:00 00 00 28,大小为40,表明位图信息字段占了40字节
- biWidth:00 00 00 19,大小为25,表明位图宽度为25像素
- biHeight:00 00 00 19,大小为25,表明位图高度为25像素
- biPlanes:00 01,大小为1,表明这张图只有一个平面
- biBitCount:00 18,大小为24,这是24位位图
- biCompression:00 00 00 00,表示没有压缩
- biSizeImage:00 00 07 6c,1900字节,表示图像的大小信息,计算方法是25*25*3+25
每一个像素的颜色信息占3个字节,为了对齐在末尾补了0,多了25字节。 - biXPlsPerMeter:00 00 00 00
- biYPlsPerMeter:00 00 00 00
- biClrUsed:00 00 00 00;为0表明没有使用调色板
- biClrImportant:00 00 00 00;表明都很重要
图像信息段
接下里要展示最精彩的部分了,那就是位图的颜色信息字段。(虽然我用的25*25的白色位图都是白色,但是不会影响分析质量)
这张图便显示了这张位图的所有颜色信息
直接从这里分析确实不好看,我把它们复制出来就好看多了。
图片太多,就不一一列举了。
从中我们可以发现,25个 ff ff ff,表示白色。最后添一个0是为了对齐,凑成4的倍数
如果把biWidth设置为4的倍数就不会出现这种问题,不信你看,这是32*25的白色图片
为什么需要对齐
这是由于Windows在进行行扫描的时候最小单位为4个字节
所以当图片宽X每个像素的字节数MOD4!=0时,以0填充。这张图有没有调色板
显然没有,因为我们这张BMP是24位真彩色的BMP,所谓真彩色图(true color),就是它的颜色数高达256×256×256种,也就是说包含我们上述提到的R、G、B颜色表示方法中所有的颜色。真彩色图并不是说一幅图包含了所有的颜色,而是说它具有显示所有颜色的能力,即最多可以包含所有的颜色。表示真彩色图时,每个象素直接用R、G、B三个分量字节表示,而不采用调色板技术。原因很明显:如果用调色板,表示一个象素也要用24位,这是因为每种颜色的索引要用24位(因为总共有256×256×256种颜色,即调色板有256×256×256行),和直接用R,G,B三个分量表示用的字节数一样,不但没有任何便宜,还要加上一个256×256×256×3个字节的大调色板。所以真彩色图直接用R、G、B三个分量表示,它又叫做24位色图。
代码
#include<iostream>#include<string>#include<cstring>#include<fstream>using namespace std;unsigned char binaryData[256*1024];int main() { string str; ifstream fin("***\\white.bmp", ios::binary|ios::app);//自己弄自己的文件吧 int length; int length_sum = 0; while (getline(fin, str)) { length = str.length(); memcpy(binaryData+length_sum, str.c_str(), length); length_sum += length; } int count = 0; for (int i = 0; i < length_sum; i++,count++) { if (count > 0 && count % 16 == 0) cout << endl; cout << hex << (int)(binaryData[i]) << " "; } fin.close(); return 0;}
Copyright© by 寒江雪
QQ:211392413
Email:211392413@qq.com
Date:2016-11-23
- 【寒江雪】BMP位图文件格式分析
- 位图(bmp)文件格式分析
- bmp位图的文件格式
- bmp位图文件格式
- bmp位图文件格式
- 位图(BMP)文件格式(一)
- BMP位图文件格式
- BMP文件格式分析
- BMP文件格式分析
- BMP文件格式分析
- BMP文件格式分析
- BMP文件格式分析
- BMP文件格式分析
- zt BMP 文件格式分析
- BMP文件格式分析
- BMP文件格式分析
- BMP文件格式分析
- BMP文件格式分析
- apk文件反编译dex2jar.bat遇到的问题
- 最短路径基本介绍(2)--Dijkstra算法(单源最短路径算法)
- 算法学习--4 设置一个有getMin功能的栈之栈的升级版(待修改)
- uva1347 Tour
- js的事件
- 【寒江雪】BMP位图文件格式分析
- Scala DataFrame生成技巧
- NetRiver - 滑动窗口协议实验
- CSDN-markdown编辑器
- JavaScript
- java.lang.ClassCastException: java.lang.Class cannot be cast to java.lang.reflect.ParameterizedType
- 3. 串的处理 在实际的开发工作中,对字符串的处理是最常见的编程任务。 本题目即是要求程序对用户输入的串进行处理。具体规则如下: 1. 把每个单词的首字母变为大写。 2. 把数字与
- HSSFWorkBooK用法 —Excel表的导出和设置
- 正则表达式---六(其他通用规则)