bmp图像文件数据分为三个部分: 1、前14个字节为文件信息头,在这部分信息中包含了位图信息标志、该bmp图像的大小和图像实际数据的相对偏移量这三部分有用的信息。 位图标志一定为“0x4D42”,否则,该文件不是bmp图像。 在VC++中,这14个字节对应一个数据类型,类型名为“BITMAPFILEHEADER”,它的定义为: typedef struct tagBITMAPFILEHEADER { WORD bfType; //位图信息标志 DWORD bfSize; //图像的大小 WORD bfReserved1; WORD bfReserved2; DWORD bfOffBits; //图像实际数据的相对偏移量 } BITMAPFILEHEADER, FAR *LPBITMAPFILEHEADER, *PBITMAPFILEHEADER; 可以设一个该类型的变量:BITMAPFILEHEADER bmfh,将bmp图像文件的前14字节数据读入这个变量中,然后通过判断bmfh.bfType == 0x4D42,确定是不是为bmp图像。 2、接下来40个字节为位图信息头,其中存储了该bmp图像的有关信息。这些信息包括:图像宽度(像素)、图像高度(像素)、图像长度(字节,仅仅是图像实际数据的长度,不包括各个信息头)、水平分辨率、垂直分辨率、每个像素的存储位数等信息。 其中,通过“每个像素的存储位数”这个信息可以知道图像的颜色: 如果“每个像素的存储位数”的值只有四种:为1,说明图像只有两种颜色(黑、白);为4,说明图像有16种颜色;为8,说明图像有256种颜色;为24,说明该图像为真彩色图像,颜色数为2^24。这四种取值对应四种bmp图像,也就是说,bmp图像只有这四种。 在这四种bmp图像种,前三种都需要在图像文件中包含调色板数据,分别存储三种图像的2、16、256种颜色。而最后一种bmp格式的图像不需要调色板,因为这种图像的“每个像素的存储位数”值为24,也就是说,存储一个像素值需要24位,正好可以存储一个像素的颜色(红、绿、蓝各8位)。 在VC++中,这40个字节的位图信息头也有一个数据类型,类型名为“BITMAPINFOHEADER”,它的定义为: 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; 3、接下来若干个字节为调色板,只有前三种bmp图像有,第四种真彩色bmp图像没有这部分数据。 调色板是一个数组,每个数组元素有四字节,只有三个字节有用,另外一个没有。有用的三个字节存储一种颜色(红绿蓝各占一字节),这四个字节在VC++中定义为: typedef struct tagRGBQUAD { BYTE rgbBlue; BYTE rgbGreen; BYTE rgbRed; BYTE rgbReserved; } RGBQUAD; 定义一个这种类型的数组即为调色板。数组的长度可由BITMAPINFOHEADER中的biBitCount推算出来。 4、上述三部分信息之后,即是实际的像素数据。一个像素的存储位数为1、4、8或16,正如前面所述。 如果是1位,对应的bmp图像应该有一个长度为2的调色板。这一位的值只能是0或1,用来指明该像素的颜色在调色板中的地址。 如果是4位,对应的bmp图像应该有一个长度为16的调色板。这4位的值有16种,同样指示该像素的颜色在调色板中的地址。 如果是8位,对应的bmp图像应该有一个长度为256的调色板。这8位的值有256种,同样指示该像素的颜色在调色板中的地址。 如果是24位,对应的bmp图像没有调色板,该像素的颜色由这24位数据直接表示。 bmp图像的数据就这几个部分。 任何一个bmp图像的像素都是由红绿蓝三种颜色组成(带调色板也好,不带调色板也好)。如果一个像素的红绿蓝三种色的值相等,那么该像素就是灰色的。灰度图是这样一种有严格规定的bmp图像:它是上述四种bmp图像的第三种,并且它的调色板的每个数组元素的红绿蓝三值都相同,所以灰度图的灰度种数是256。 若要保存图像,需要按顺序保存文件信息头、位图信息头、调色板(如果有)和图像的实际数据。程序可以这样写: bool Write(CString FileName) { CFile file; BITMAPFILEHEADER bmfh; if(! (bmi && pBits)) { AfxMessageBox("Data is not valid!"); return FALSE; } //创建文件 if(!file.Open(FileName,CFile::modeCreate | CFile::modeWrite)) { AfxMessageBox("File creating fails!"); return FALSE; } //填写文件信息头 bmfh.bfType = 0x4d42; bmfh.bfReserved1 = bmfh.bfReserved2 = 0; int nInfoSize = sizeof(BITMAPINFOHEADER) + GetPaletteSize() * sizeof(RGBQUAD); bmfh.bfOffBits = sizeof(bmfh) + nInfoSize; bmfh.bfSize = bmfh.bfOffBits + bmi->bmiHeader.biSizeImage; //写文件 file.Write( (LPVOID)&bmfh, sizeof(bmfh)); file.Write( (LPVOID)bmi, nInfoSize); file.Write( (LPVOID)pBits, bmi->bmiHeader.biSizeImage); return TRUE; } http://wenku.baidu.com/view/550a8fd049649b6648d7478a.html http://wenku.baidu.com/view/fe8ff04ffe4733687e21aa95.html http://wenku.baidu.com/view/c2438ceb6294dd88d0d26b95.html http://wenku.baidu.com/view/685704a1284ac850ad024295.html
BMP数据说明
最新推荐文章于 2023-02-11 09:20:16 发布