C++学习(三三四)BMP图片文件结构

Posted hankern

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C++学习(三三四)BMP图片文件结构相关的知识,希望对你有一定的参考价值。


    typedef struct tagBITMAP_FILE{
     
          BITMAPFILEHEADER bitmapheader;
          BITMAPINFOHEADER bitmapinfoheader;
          PALETTEENTRY palette[256];
          UCHAR *buffer;   //UCHAR 大小1字节(同BYTE), 在VC6下
     
    } BITMAP_FILE;

typedef struct tagBITMAPFILEHEADER { 
WORD    bfType; 
DWORD   bfSize; 
WORD    bfReserved1; 
WORD    bfReserved2; 
DWORD   bfOffBits; 
} BITMAPFILEHEADER, FAR *LPBITMAPFILEHEADER, *PBITMAPFILEHEADER;

typedef struct tagBITMAPINFOHEADER{ 
DWORD      biSize; 
LONG        biWidth; 
LONG        biHeight; 
WORD       biPlanes; 
WORD       biBitCount; 
DWORD      biCompression; 
DWORD      biSizeImage; 
LONG        biXPelsPerMeter; 
LONG        biYPelsPerMeter; 
DWORD      biClrUsed; 
DWORD      biClrImportant; 
} BITMAPINFOHEADER, FAR *LPBITMAPINFOHEADER, *PBITMAPINFOHEADER;

 1.位图文件头(bitmap-file header):包含BMP图像文件的类型、显示内容等信息。BITMAPFILEHEADER下的bfType。它是文件标识,如果值不是0x4D42,就表明这张根本不是BMP。

字 段 名

大小(单位:字节)

描 述

bfType

2

位图类别,根据不同的操作

系统而不同,在Windows

中,此字段的值总为‘BM’

bfSize

4

BMP图像文件的大小

bfReserved1

2

总为0

bfReserved2

2

总为0

bfOffBits

4

BMP图像数据的地址

    2.位图信息头(bitmap-information header):包含有BMP图像的宽、高、压缩方法,以及定义颜色等信息。BITMAPINFOHEADER下的biBitCount。它代表了BMP的位数。常用的BMP有8位,16位,24位(RGB),32位(RGBA)。

大小

(单位:

字节)

描 述

biSize

4

本结构的大小,根据不同的操作系统而不同,在Windows中,此字段的值总为28h字节=40字节

biWidth

4

BMP图像的宽度,单位像素

biHeight

4

总为0

biPlanes

2

总为0

biBitCount

2

BMP图像的色深,即一个像素用多少位表示,常见有1、4、8、16、24和32,分别对应单色、16色、256色、16位高彩色、24位真彩色和32位增强型真彩色

biCompression

4

压缩方式,0表示不压缩,1表示RLE8压缩,2表示RLE4压缩,3表示每个像素值由指定的掩码决定

biSizeImage

4

BMP图像数据大小,必须是4的倍数,图像数据大小不是4的倍数时用0填充补足

biXPelsPerMeter

4

水平分辨率,单位像素/m

biYPelsPerMeter

4

垂直分辨率,单位像素/m

biClrUsed

4

BMP图像使用的颜色,0表示使用全部颜色,对于256色位图来说,此值为100h=256

biClrImportant

4

重要的颜色数,此值为0时所有颜色都重要,对于使用调色板的BMP图像来说,当显卡不能够显示所有颜色时,此值将辅助驱动程序显示颜色

    3.BITMAPINFOHEADER下的biCompression。它表示BMP图片的压缩方式。是的,BMP也能压缩,只不过可能跟你想象的那个“压缩”有点不一样。方式(BI_RGB   BI_RLE8   BI_RLE4  BI_BITFIELDS)中最前一个表示无压缩,最后一个在16位时表示RGB的565存放,我就知道这么多。

    4.BITMAPINFOHEADER下的biSizeImage,biWidth,biHeight;biSizeImage理应=biWidth*biHeight*biBitCount,但是有些图片直接读下来这个值是0的。所以数据大小还是用等式右边得出比较好。另外,BMP数据默认是按行倒置的(biHeight>0),但偶尔也会出现biHeight<0,图片数据无倒置的情况。

5.彩色表/调色板(color table):这个部分是可选的,有些位图需要调色板,有些位图,比如真彩色图(24位的BMP)就不需要调色板。另外不得不提的是PALETTEENTRY调色板。8位模式下是调色板(颜色索引);在16位模式下,在biCompression为BI_BITFIELDS的时候存储的是565的16位BMP的掩码(测试过),在biCompression为BI_BI_RGB 的时候存555的16位BMP掩码。

5.位图数据(bitmap-data):这部分的内容根据BMP位图使用的位数不同而不同,在24位图中直接使用RGB,而其他的小于24位的使用调色板中颜色索引值。数据是以UCHAR(BYTE)来存储的。而 1 BYTE = 8BIT。所以很明显地,24BIT = 3 * 8BIT,也就是说数据里头每三个数据为一组,分别描述一个B,G,R的值(注意,BMP里面都是BGR顺序),每个分量的范围是0~2^8-1,也就是0~255,跟我们日常所见一致。32BIT多出的8BIT就存ALPHA值了(注意是BGRA顺序)。而8BIT就是说每字节(8BIT)就描述一种颜色,共256“色”了。那怎么知道某个值(譬如120)代表什么颜色呢?调色板起作用了。调色板PALETTEENTRY结构就是一个RGB结构(外加一个保留字,有时用作ALPHA),如果对应的palette[120] = (255,255,0,*)的话,数据区内那个值为120的数据就表示黄色了。可见256“色”不是真的256色(当然,8位的灰度图就真的是256色了)。问题是麻烦的16位(2BYTE),它又怎样呢?在这16个位里,可以是第1位保留,其余15位均分给BGR(传说中的555,每个分量可为0~2^5-1,即0~31,比24位差远了,可见8位也可以比16位“高级”的嘛);也可以是按5-6-5分配给BGR,因为人对绿色的XXX范围(?)比较大,也就有了上述的压缩模式,根据掩码判别。当然还有其他的。

以上是关于C++学习(三三四)BMP图片文件结构的主要内容,如果未能解决你的问题,请参考以下文章

C++学习(三三三)Android查看目录下的文件列表

C++学习(三四八)CLang GCC

C++加密bmp图片程序

C++实现红外Fir谱图文件转BMP图片文件

关于怎么用C++读取bmp图片

用c ++读取BMP文件的所有字节并旋转图片