BMP 文件结构分成以下几个部分:
1 BITMAP FILEHEADER (BMP 文件头)
2 BITMAP INFOHEADER (BMP 文件信息头)
3 RGBQUAD (BMP 文件调色板)
4 BITMAP DATA (BMP 文件数据)
Windows 中位图有两种格式:
设备相关位图 Device Depend Bitmap DDB
设备无关位图 Device Independ Bitmap DIB
DDB 位图格式 ------------ BITMAP(结构体) CBitmap(MFC类) HBITMAP(HANDLE)
由 BITMAP 数据类型的结构 + 图像数据构成。
因为DDB没有保存位图的调色板,在不同类设备显示时可能造成完全失真。
DIB 位图格式 ----------- BITMAPINFO
BITMAP INFOHEADER (BMP 文件信息头) + RGBQUAD (BMP 文件调色板) + BITMAP DATA (BMP 文件数据) 三部分构成
它实际就是BMP文件去掉BITMAP FILEHEADER (BMP 文件头),即一个BITMAPINFO结构后面接上调色板再加上图像数据。
BMP文件的显示 ---- DIB
首先将BMP读成DIB格式,当显示时直接DIB显示,只要读入BITMAPINFO结构和图像数据即可。
BMP文件的显示 ---- DDB
首先要先将DIB位图转化为DDB位图,再由MFC的CBitmap类显示。
总结: 统一使用DIB显示,即 BITMAPINFO;//个人意见
不要使用以下:BITMAP(结构体) CBitmap(MFC类) HBITMAP(HANDLE)//个人意见
//**********************************************
重点说说 BITMAPINFO MFC中的定义如下:
typedef struct tagBITMAPINFO {
} BITMAPINFO, FAR *LPBITMAPINFO, *PBITMAPINFO;
这个结构体定义很奇怪,大概的意思是兼容没有调色板的情况,不看它的写法,
依据BITMAPINFO的大小为 sizeof(BITMAPINFOHEADER) + numQuad * sizeof(RGBQUAD)
BITMAPINFOHEADER INFO_HEADER; //信息头
//====================BITMAPINFO 说明=====================================
typedef struct tagBITMAPINFO {
} BITMAPINFO, FAR *LPBITMAPINFO, *PBITMAPINFO;
在一个结构体定义
RGBQUAD bmiColors[1];
是很危险也非常巧妙的不得已的办法,它的存在只为照顾bmp文件而存在;
因此使用BITMAPINFO有很多限制:
限制一 RGBQUAD bmiColors[1];此类设置只能存在1个,且必在最后
限制二 RGBQUAD类型必为4字节的整倍数
限制三 虽然sizeof(BITMAPINFO) = 40 + 4 = 44;
bmp文件的字节是连续的(当然任何文件都是连续的),在文件中,紧随BITMAPINFOHEADER之后是调色板,如果没有调色板,紧随BITMAPINFOHEADER之后是数据,注意如果没有调色板,在BITMAPINFOHEADER与数据之间没有任何字节存在,为了照顾bmp文件BITMAPINFO被设计成这样,bmiColors[1]是个数组,它存放了数组的第1个元素,也就是bmiColors[0],接下来一定是bmiColors[1](此bmiColors[1]表示RGBQUAD数组的第2个元素,而BITMAPINFO中RGBQUAD bmiColors[1];则表示定义一个类型,是一个数组,因为数组是连续存储的,这样设计才能保证与bmp文件结构吻合),好乱~
申请内存也可这样写:
BITMAPINFO *pBMP_INFO = (BITMAPINFO*)malloc(sizeof(BITMAPINFOHEADER) + numQuad * sizeof(RGBQUAD));
BITMAPINFO *pBMP_INFO = new BITMAPINFO[sizeof(BITMAPINFOHEADER) + numQuad * sizeof(RGBQUAD)];