BMP文件解析【转】
本文转载自:http://blog.csdn.net/Blues1021/article/details/44954817
BMP文件通常是不压缩的,所以它们通常比同一幅图像的压缩图像文件格式要大很多。例如,一个800×600的24位几乎占据1.4MB空间。因此它们通常不适合在因特网或者其他低速或者有容量限制的媒介上进行传输。
根据颜色深度的不同,图像上的一个像素可以用一个或者多个字节表示,它由n/8所确定(n是位深度,1字节包含8个数据位)。图片浏览器等基于字节的ASCII值计算像素的颜色,然后从调色板中读出相应的值。更为详细的信息请参阅下面关于位图文件的部分。
n位2n种颜色的包含调色板的位图近似字节数可以用下面的公式计算:
BMP文件大小,其中高度(height)和宽度(width)都以像素为单位。
需要注意的是上面公式中的54是位图文件的文件头,4*2(^n)是彩色调色板的大小。 如果位图文件不包含调色板,如24位,32位位图,则位图的近似字节数可以用下面的公式计算:
BMP文件大小,其中高度(height)和宽度(width)都以像素为单位。
另外需要注意的是这是一个近似值,对于n位的位图图像来说,尽管可能有最多2(^n)种颜色,一个特定的图像可能并不会使用这些所有的颜色。由于彩色调色板仅仅定义了图像所用的颜色,所以实际的彩色调色板将小于4*2(^n)。
如果想知道这些值是如何得到的,请参考下面文件格式的部分。
由于存储算法本身决定的因素,根据几个图像参数的不同计算出的大小与实际的文件大小将会有一些细小的差别。
BMP文件如果像素色深是8位及以下,那么会采用调色板形成索引位图,否则不会采用调色板。
1.BMP的头文件[必须】:
typedef struct tagBITMAPFILEHEADER {
WORD bfType; // 42 4D是windows BMP文件标识,其它的文件还有其它的标识
DWORD bfSize; // 整个文件的大小
WORD bfReserved1; // 保留位不使用,为0
WORD bfReserved2; // 保留位不使用,为0
DWORD bfOffBits; // 位图数据文件,在整个文件中的偏移(跳过BMP头,位图头,调色板(如果有))
} BITMAPFILEHEADER, FAR *LPBITMAPFILEHEADER, *PBITMAPFILEHEADER;
2.BMP位图信息头说明文件[必须]:
typedef struct tagBITMAPINFOHEADER{
DWORD biSize; // 信息头的大小
LONG biWidth; // 图像数据宽度,单位是像素
LONG biHeight; // 图像数据高度,单位是像素,且如果是正数那么是倒向的位图,也就是2D屏幕坐标系翻转类似物体坐标系(y轴由下到上,位图数据也由左下角一行行的存放),如果是负数,那么图像是正向的,也就是2D屏幕坐标系(y轴由上到下,位图数据也由左上角一行行存放).
WORD biPlanes; // 颜色平面数,总是1
WORD biBitCount; // 每个像素的比特数,一般是8,16,24,32;8的话一般包含调色板,其它位数多的,调色板太大了,一般不用。
DWORD biCompression; // 0不压缩;1,2比特游程编码就是霍夫曼编码上的值+重复数标记; 3是比特域编码减少字节的使用,4是位图包含JPEG图像用于打印,5是位图包含PNG图像用于打印。
DWORD biSizeImage; // 图像数据的字节数大小。
LONG biXPelsPerMeter; // 水平分辨率,像素/米,给打印参考或显示缩放图片兼容用的,具体屏幕上的显示大小会根据像素数/屏幕像素密度得到。
LONG biYPelsPerMeter; // 垂直分辨率,像素/米,给打印参考或显示缩放图片兼容用的,具体屏幕上的显示大小会根据像素数/屏幕像素密度得到。
DWORD biClrUsed; // 说明位图实际使用的调色板中的颜色索引数如果是8位一像素那么这里是256;为0采用所用调色板中的索引或者没有调色板。
DWORD biClrImportant; // 调色板中对图像显示有重要影响的颜色索引数如果是8位一像素那么这里是256;为0都重要,或者没有调色板。
} BITMAPINFOHEADER, FAR *LPBITMAPINFOHEADER, *PBITMAPINFOHEADER;
3.调色板[可选]
4.位图数据(是索引或者像素值) [必须]
位图图片像素数据真正存放的地方。
8位BMP,每个位图存放的是调色板中的索引,如果像素高度是正数那么是物体坐标系,位图数据由左下角一行行往上存放。
如果是非调色板真彩色像素,那么存放的就是颜色值,而不是索引,像素高度是正数那么是物体坐标系由左下角开始,像素高度是负数那么是屏幕物体坐标系由左上角开始。24位RGB按照BGR的顺序来存储每个像素的各颜色通道的值,一个像素的所有颜色分量值都存完后才存下一个下一个像素,不进行交织存储。32位数据按照BGRA的顺序存储,其余与24位位图的方式一样。
当高度为正数确实是物体坐标系形式,无论是内存中还是二进制文件中,像素由图像的左下角一行行往上存放;当高度为负数那么是屏幕坐标系,像素是由图像左上角一行行往下存放;如果一行不足4字节的倍数,那么填充00使得满足4字节的倍数。
参考文章:
http://blog.csdn.net/o_sun_o/article/details/8351037