logo资料库

一个将图像数据保存为BMP文件的实例.doc

第1页 / 共4页
第2页 / 共4页
第3页 / 共4页
第4页 / 共4页
资料共4页,全文预览结束
一个将图像数据保存为 BMP 文件的实例 BMP 文件是 Windows 保存图像的一种通用文件格式,在数字图像处理方面占有重要的地位。BMP 文件中 保存的图像数据是一种 DIB(Device-Independent Bitmap,即设备无关位图),DIB 是标准的 Windows 位图 格式,它自带颜色信息,因此调色板管理非常容易。有许多文章是关于讲述如何将 BMP 文件读取、显示的, 而如何将数据保存为 BMP 文件则不是太多,本文作者通过一个实例讲述这一过程。 一、BMP 文件的结构 要想把数据正确地保存为 BMP 文件,首先对 BMP 文件的结构应该有一个清晰的了解。一个 BMP 文件大 体上分成如下 4 个部分,如图 1 所示。 BITMAPFILEHEADER 位图文件头 (只用于BMP文件) BITMAPINFOHEADER 位图信息头 bfType = “BM” bfSize bfReserved1 bfReserved2 bfOffBits biSize biWidth biHeight biPlance biBitCount biCompression biSizeImage biXPelsPerMeter biYPelsPerMeter biClrUsed biClrImportant Palette 调色板 单色 DIB 有 2 个表项 16 色 DIB 有 16 个表项或更少 256 色 DIB 有 256 个表项或更少 真彩色 DIB 没有调色板 DIB Pixels DIB图像数据 象素按照每行每列的顺序排列 每一行的字节数必须是 4 的整倍数 图 1 BMP 文件结构示意图 1、 第一部分为位图文件头 BITMAPFILEHEADER,它是一个结构,其定义如下: typedef struc tagBITMAPFILEHEADER{ WORD WORD WORD WORD WORD bfType; bfSize; bfReserved1; bfReserved2; bfOffBits; 1
}BITMAPFILEHEADER, FAR *LPBITMAPFILEHEADER, *PBITMAPFILEHEADER; 该结构的长度是固定的,为 14 个字节,各个域的说明如下:  bfType:指定文件类型,必须是 0x4d42,即字符串“BM”。  bfSize:指定文件大小,包括这 14 个字节。  bfReserved1,bfReserved2:保留字,为 0。  bfOffBits:从文件头到实际的位图数据的偏移字节数,即图 1 中前三个部分的长度之和。 2、 第二部分为位图信息头 BITMAPINFOHEADER,它也是一个结构,其定义如下: typedef struc tagBITMAPINFOHEADER{ DWORD LONG LONG WORD WORD DWORD DWORD LONG LONG DWORD DWORD biSize; biWidth; biHeight; biPlanes; biBitCount; biCompression; biSizeImage; biXPelsPerMeter; biYPelsPerMeter; biClrUsed; biClrImportant; }BITMAPINFOHEADER, FAR *LPBITMAPINFOHEADER, *PBITMAPINFOHEADER; 该结构的长度也是固定的,为 40 个字节,各个域的说明如下:  biSize:指定这个结构的长度,为 40 个字节。  biWidth:指定图像的宽度,单位是象素。  biHeight:指定图像的高度,单位是象素。  biPlanes:必须是 1。  biBitCount:指定表示颜色时用到的位数,常用的值为 1(黑白二色图)、4(16 色图)、8(256 色图)、24(真彩色图)。  biCompression:指定位图是否压缩,有效值为 BI_RGB,BI_RLE8,BI_RLE4,BI_BITFIELDS。 Windows 位图可采用 RLE4 和 RLE8 的压缩格式,BI_RGB 表示不压缩。  biSizeImage:指定实际的位图数据占用的字节数,可用以下的公式计算出来: biSizeImage = biWidth’× biHeight 要注意的是:上述公式中的 biWidth’必须是 4 的整数倍(不是 biWidth,而是大于或等于 biWidth 的离 4 最近的整数倍)。如果 biCompression 为 BI_RGB,则该项可能为 0。  biXPelsPerMeter:指定目标设备的水平分辨率。  biYPelsPerMeter:指定目标设备的垂直分辨率。  biClrUsed:指定本图像实际用到的颜色数,如果该值为 0,则用到的颜色数为 2 的 biBitCount 次幂。  biClrImportant:指定本图像中重要的颜色数,如果该值为 0,则认为所有的颜色数都是重要 的。 3、 第三部分为调色板。有些位图需要调色板,有些位图,如真彩色图,不需要调色板, 它们的 BITMAPINFOHEADER 后面直接是位图数据。 调色板实际上是一个数组,共有 biClrUsed 个元素(如果该值为 0,则有 2 的 biBitCount 次幂个元 素)。数组中每个元素的类型是一个 RGBQUAD 结构,占 4 个字节,其定义如下: typedef struct tagRGBQUAD{ BYTE BYTE rgbBlue; rgbGreen; 2
BYTE BYTE rgbRed; rgbReserved; }RGBQUAD; 其中:  rgbBlue:该颜色的蓝色分量。  rgbGreen:该颜色的绿色分量。  rgbRed:该颜色的红色分量。  rgbReserved:保留值。 4、 第四部分就是实际的图像数据。对于用到调色板的位图,图像数据就是该象素颜色在调色板中的 索引值,对于真彩色图,图像数据就是实际的 R、G、B 值。  对于 2 色图,用 1 位就可以表示该象素的颜色,所以 1 个字节可以表示 8 个象素。  对于 16 色图,用 4 位可以表示一个象素的颜色,所以 1 个字节可以表示 2 个象素。  对于 256 色图,1 个字节刚好可以表示 1 个象素。  对于真彩色图,3 个字节才能表示 1 个象素。 二、保存实例 1、 图像数据 图像数据来源于图像采集卡所采集的图像的一部分,保存在一 Buffer 中(char *lp1),图像高度为 110 个象素(保存在变量 int m_Width 中),宽度为 228 个象素(保存在变量 int m_Height 中,并且是 4 的整倍 数),图像为一 256 色灰度图。 2、实例代码 BITMAPFILEHEADER bmfHdr; //定义文件头 BITMAPINFOHEADER bmiHdr; //定义信息头 RGBQUAD rgbQuad[256]; //定义调色板 //对信息头进行赋值 bmiHdr.biSize = sizeof(BITMAPINFOHEADER); //指定这个结构的长度 bmiHdr.biWidth = m_WidthOfModel; //指定图像的宽度 bmiHdr.biHeight = m_HeightOfModel; //指定图像的高度 bmiHdr.biPlanes = 1; bmiHdr.biBitCount = 8; bmiHdr.biCompression = BI_RGB; //指定位图是否压缩 bmiHdr.biSizeImage = m_WidthOfModel*m_HeightOfModel; //指定实际的位图数据占用的字 // 指定图像的位数,必须是 1 //指定表示颜色时用到的位数 节数 bmiHdr.biXPelsPerMeter = 0; bmiHdr.biYPelsPerMeter = 0; bmiHdr.biClrUsed = 0; bmiHdr.biClrImportant = 0; //对调色板进行赋值 for(i=0; i<256; i++) { rgbQuad[i].rgbBlue = (BYTE)i; rgbQuad[i].rgbGreen = (BYTE)i; rgbQuad[i].rgbRed = (BYTE)i; rgbQuad[i].rgbReserved = 0; } //对文件头进行赋值 bmfHdr.bfType = (WORD)0x4D42; //;((WORD)('M'<<8) | 'B') 3
bmfHdr.bfSize=(DWORD)(sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+ sizeof(RGBQUAD)*256 + m_WidthOfModel*m_HeightOfModel); //指定文件大小 bmfHdr.bfReserved1 = 0; bmfHdr.bfReserved2 = 0; bmfHdr.bfOffBits=(DWORD)(sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFO HEADER)+sizeof(RGBQUAD)*256); //从文件头到实际的位图数据的偏移 字节数 //保存文件 CFile fp; fp.Open("d:\\Model.bmp",CFile::modeCreate | CFile::modeWrite); fp.Write((LPSTR)&bmfHdr,sizeof(BITMAPFILEHEADER)); //写文件头 fp.Write((LPSTR)&bmiHdr,sizeof(BITMAPINFOHEADER)); //写信息头 fp.Write((LPSTR)rgbQuad,sizeof(RGBQUAD)*256); //写调色板 fp.Write(lpvBuffer2Bits,m_WidthOfModel*m_HeightOfModel);//写数据 fp.Close(); 以上代码在 VC++5.0 环境调试通过。 2、 实例图像 图 2 为通过以上代码保存的图像文件 Model.bmp。 三、结束语 图 2 本文作者对 BMP 文件的结构进行了较为清晰的剖析,对各部分的变量作了较为详尽的说明,并给 出了将图像数据保存为 BMP 文件实例的详细代码,原代码在 VC++5.0 环境下调试通过。 参考文献 1、 何斌 等编著.Visual C++数字图像处理.人民邮电出版社,北京,2001.4 2、 王晖 等编著.精通 Visual C++ 6.0.电子工业出版社,北京,2001.6 4
分享到:
收藏