BMP格式图像说明一、bmp文件总体结构位图文件可看成由4个部分组成:位图文件头(bitmap-fileheader)、位图信息头(bitmap-informationheader)、彩色表(colortable)和定义位图的字节阵列,它们的名称和符号如表6-01所示。表6-01BMP图像文件组成部分的名称和符号位图文件的组成结构名称符号位图文件头(bitmap-fileheader)BITMAPFILEHEADERbmfh位图信息头(bitmap-informationheader)BITMAPINFOHEADERbmih彩色表(colortable)RGBQUADaColors[]图像数据阵列字节BYTEaBitmapBits[]以下将分别说明:1、文件头:BITMAPFILEHEADERbmfh;//位图文件头typedefstructtagBITMAPFILEHEADER{UINTbfType;//文件标志DWORDbfSize;//文件大小UINTbfReserved1,bfReserved2;DWORDbfOffBits;//数据偏移}BITMAPFILEHEADER;具体说明:偏移量域的名称大小内容图像0000h标识符(bfType)2bytes两字节的内容用来识别位图的类型:‘BM’:Windows3.1x,95,NT,…‘BA’:OS/2BitmapArray‘CI’:OS/2ColorIcon文件头‘CP’:OS/2ColorPointer‘IC’:OS/2Icon‘PT’:OS/2Pointer0002hbfSize1dword用字节表示的整个文件的大小,等于位图文件头+信息头+颜色表+位数据。以字节为单位即:sizeof(bmfh)+sizeof(bmih)+sizeof(RGBQUAD)*256+bmih.biSizeImae0006hbfReserved1,bfReserved21dword保留,设置为0000AhbfOffBits1dword从文件开始到位图数据开始之间的数据(bitmapdata)之间的偏移量,(即位图文件头+信息头+颜色表的字节数)2、位图信息用BITMAPINFO结构来定义,它由位图信息头(bitmap-informationheader)和彩色表(colortable)组成,前者用BITMAPINFOHEADER结构定义,后者用RGBQUAD结构定义。BITMAPINFO结构具有如下形式:typedefstructtagBITMAPINFO{BITMAPINFOHEADERbmiHeader;RGBQUADbmiColors[256];//其中256表示8位灰度图像的颜色数}BITMAPINFO;信息头:BITMAPINFOHEADERbmih;//位图信息头typedefstructtagBITMAPINFOHEADER{DWORDbiSize;//信息头大小。40字节LONGbiWidth,biHeight;//位图实际宽、高度。WORDbiPlanes;//WORDbiBitCount;//位图每像素的位数。DWORDbiCompression;//DWORDbiSizeImage;//位数据的大小(字节)LONGbiXPelsPerMeter,biYPelsPerMeter;//DWORDbiClrUsed;//DWORDbiClrImprotant;//}BITMAPINFOHEADER;颜色表:typedefstructtagRGBQUAD{BYTErgbBlue;BYTErgbGreen;BYTErgbRed;BYTErgbReserved;}RGBQUAD;对于8位的灰度图,颜色表的值为:RGBQUADbmiColors[256];for(i=0;i256;i++){bmiColors[i].rgbBlue=(BYTE)i;bmiColors[i].rgbGreen=(BYTE)i;bmiColors[i].rgbRed=(BYTE)i;bmiColors[i].rgbReserved=(BYTE)0;}具体含义如下:000EhbiSize1dword位图信息头(BitmapInfoHeader)的长度,用来描述位图的颜色、压缩方法等。下面的长度表示:28h(40字节)-Windows3.1x,95,NT,0Ch-OS/21.xF0h-OS/22.x…0012hbiWidth1dword位图的宽度,以像素为单位,对于64*64的图像,则biWidth为64,具体视情况而定,其值为500字节的数据的前64个字节中的“有效列数”信息0016hbiHeight1dword位图的高度,以像素为单位,对于64*64的图像,则biHeight为64,具体视情况而定,其值为500字节的数据的前64个字节中的“有效行数”信息001AhbiPlanes1word位图的位面数,对于灰度图像,位面数为1图像信息头001ChbiBitCount1word每个像素的位数1-Monochromebitmap4-16colorbitmap8-256colorbitmap,在一体化项目中每个像素的位数为816-16bit(highcolor)bitmap24-24bit(truecolor)bitmap32-32bit(truecolor)bitmap001EhbiCompression1dword压缩说明:0-none(也使用BI_RGB表示),当选择此压缩方式时,biSizeImage的值可设为01-RLE8-bit/pixel(也使用BI_RLE4表示)2-RLE4-bit/pixel(也使用BI_RLE8表示)3-Bitfields(也使用BI_BITFIELDS表示)0022hbiSizeImage1dword用字节数表示的位图数据的大小。该数必须是4的倍数,对于64*64的bmp图像,则位图数据区大小为4096,具体视情况而定,其值为每包500字节的数据的前64个字节中的图像大小信息;这里有需要注意的:位图数据每行是以4字节增充的,如果是一个256色的位图。它的像素占一字节。如果图像宽度为80像素,则图像每行为80字节,如果图像宽度为79像素,则磁盘上的位图文件仍然是80字节。(78,77像素每行也为80字节)。图像每行76,75,74,73像素,则它在文件中占76个字节。0026hbiXPelsPerMeter1dword用像素/米表示的水平分辨率002AhbiYPelsPerMeter1dword用像素/米表示的垂直分辨率002EhbiClrUsed1dword位图使用的颜色数。如8-位/像素表示为100h或者256.0032hbiClrImprotant1dword指定重要的颜色数。当该域的值等于颜色数时,表示所有颜色都一样重要,调色板数据0036hRGBQUADN*4byte调色板规范。对于调色板中的每个表项,这4个字节用下述方法来描述RGB的值:1字节用于蓝色分量1字节用于绿色分量1字节用于红色分量1字节用于填充符(设置为0),N表示颜色板中的颜色数3.像素数据:紧跟在彩色表之后的是图像数据字节阵列。图像的每一扫描行由表示图像像素的连续的字节组成,每一行的字节数取决于图像的颜色数目和用像素表示的图像宽度。扫描行是由底向上存储的,这就是说,阵列中的第一个字节表示位图左下角的像素,而最后一个字节表示位图右上角的像素。图像数据0436hBitmapDataxbytes该域的大小取决于压缩方法,它包含所有的位图数据字节,这些数据实际就是彩色调色板的索引号二、64*64的8位灰度图像的BMP格式图像存储c语言程序示例:BITMAPFILEHEADERtargetfileheader;BITMAPINFOHEADERtargetinfoheader;memset(&targetfileheader,0,sizeof(BITMAPFILEHEADER));memset(&targetinfoheader,0,sizeof(BITMAPINFOHEADER));//构造灰度图的文件头targetfileheader.bfOffBits=(DWORD)sizeof(BITMAPFILEHEADER)+(DWORD)sizeof(BITMAPINFOHEADER)+sizeof(RGBQUAD)*256;targetfileheader.bfSize=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+sizeof(RGBQUAD)*256+64*64;targetfileheader.bfReserved1=0;targetfileheader.bfReserved2=0;targetfileheader.bfType=0x4d42;//构造灰度图的信息头targetinfoheader.biBitCount=8;targetinfoheader.biSize=sizeof(BITMAPINFOHEADER);targetinfoheader.biHeight=64;targetinfoheader.biWidth=64;targetinfoheader.biPlanes=1;targetinfoheader.biCompression=BI_RGB;targetinfoheader.biSizeImage=0;targetinfoheader.biXPelsPerMeter=0;targetinfoheader.biYPelsPerMeter=0;targetinfoheader.biClrImportant=0;targetinfoheader.biClrUsed=0;//构造灰度图的调色版RGBQUADbmiColors[256];inti;for(i=0;i256;i++){bmiColors[i].rgbBlue=i;bmiColors[i].rgbGreen=i;bmiColors[i].rgbRed=i;bmiColors[i].rgbReserved=0;}//构造灰度图的像素数据BYTE*targetbuf;targetbuf=newBYTE[64*64];//设置像素数据的存储空间//由于BMP图像对于行是倒置的,即图像显示的第一行是最后一行数据,所以要倒置,这里的pcutface是原始的灰度图像,即为从小盒子收到的有效像素数据for(longi=63;i=0;i--){for(longj=0;j64;j++){targetbuf[i*64+j]=pcutface[(63-i)*64+j];}}CFilecf;if(!cf.Open(LPCTSTR(f:\\fire.BMP),CFile::modeCreate|CFile::modeWrite))return;cf.Write(&targetfileheader,sizeof(BITMAPFILEHEADER));cf.Write(&targetinfoheader,sizeof(BITMAPINFOHEADER));cf.Write(&rgbquad,sizeof(RGBQUAD)*256);cf.Write(targetbuf,64*64);//这里targetbuf的大小为64x64cf.Close();