1、载入位图、并提取其中信息及显示图像的方法1 定义文件对象、文件头对象、文件信息对象(并不是文件信息头对象) 、图像数据指针:CFile file;DWORD DIBSize;BITMAPFILEHEADER bmpfheader;BITMAPINFO *pbmpinfo;LPSTR pbmpData=NULL;解释一下文件信息对象BITMAPINFO,结构如下:typedef struct tagBITMAPINFO BITMAPINFOHEADER bmiHeader; RGBQUAD bmiColors1; BITMAPINFO, *PBITMAPINFO; BITMAPINFO包括文件信
2、息头BITMAPINFOHEADER bmiHeader和调色板数组RGBQUAD bmiColors1(这里写成元素个数为1 是因为bmiColors1其实是一个地址,也可以看成一个指针,后面的元素个数并不重要,可以是任意个) 。2 调用 file对象Open 方法,打开文件:if(!file.Open(_T(“D:8b.bmp“),CFile:modeReadWrite)MessageBox(_T(“打开文件错误“);return;3 读取文件头if (sizeof(bmpfheader)!=file.Read(return;4 判断文件格式是否是BMP格式,否则返回if(bmpfhead
3、er.bfType=DIB_HEADER_MARKER)MessageBox(_T(“BMP格式“);elseMessageBox(_T(“其它格式“);return;文件头结构的定义:typedef struct tagBITMAPFILEHEADER WORD bfType; 指定文件格式DWORD bfSize; 指定这个结构的长度,为 14 字节WORD bfReserved1; 保留字WORD bfReserved2; 保留字DWORD bfOffBits; 从文件头到实际的位图数据的偏移字节数 BITMAPFILEHEADER, *PBITMAPFILEHEADER; 可见,获得文
4、件头数据即可判断该文件是否是BMP格式文件。5 获得DIB。获得DIB大小,即除去文件头外的文件大小,以为DIB句柄分配内存,并获得指向该内存的指针5.1获得DIB大小DIBSize=file.GetLength()-sizeof(bmpfheader);5.2调用GlobalAlloc函数为DIB分配内存:HDIB hDIB=(HDIB):GlobalAlloc(GMEM_MOVEABLE|GMEM_ZEROINIT,DIBSize+sizeof(bmpfheader);if (hDIB=NULL)MessageBox(_T(“分配内存错误“);return;5.3调用GlobalLock、
5、GlobalUnlock方法,获得指向该内存的指针,即指向DIB的指针LPSTR pDIB=(LPSTR):GlobalLock(HGLOBAL)hDIB);:GlobalUnlock(HGLOBAL)hDIB);5.4为DIB内存填充数据,用CFILE:READ方法将BMP中所包含的DIB数据读入到刚分配到的DIB内存中,读入数据的大小即为图像文件总的大小减去文件头的大小。if (file.Read(pDIB,DIBSize)!=DIBSize)MessageBox(_T(“读取图像信息及数据错误“);return;6 获得图像数据指针。方法一:由于文件头中记录了图像数据与言论文件头偏离的地
6、址长度,因以可以这样得到:图像数据指针=DIB指针+从文件头偏移的长度-文件头长度:pbmpData=pDIB+bmpfheader.bfOffBits-sizeof(bmpfheader);方法二:图像数据指针=DIB指针+文件信息头大小(*(LPDWORD)pDIB)+调色板大小(颜色数*RGBQUAD结构)6.1 上式中文件信息头大小(*(LPDWORD)pDIB)的说明:DIB指针指向的是整个DIB数据的开始位置,也就是文件信息头的开始位置,文件信息头的结构如下:typedef struct tagBITMAPINFOHEADERDWORD biSize; 这个结构的长度LONG bi
7、Width; 图像的宽度LONG biHeight; 图像的高度WORD biPlanes; 必须是 1WORD biBitCount; 指定表示颜色时要用到的位数,例如 8(256 色)DWORD biCompression; 指定位图是否压缩,BI_RGB 为不压缩DWORD biSizeImage; 指定实际的位图数据占用的字节数LONG biXPelsPerMeter; 指定目标设备的水平分辨率LONG biYPelsPerMeter; 指定目标设备的垂直分辨率DWORD biClrUsed; 用到的颜色数DWORD biClrImportant; 指定图像中重要的颜色数 BITMAP
8、INFOHEADER, *PBITMAPINFOHEADER; 可见biSize是本结构的第一个元素,它表示这个结构的长度,因此DIB指针也指向它。(*(LPDWORD)pDIB)就是提取到该元素的值。6.2 调色板的大小。调色板实际是一个RGBQUAD的数组,元素个数为图像中用到的颜色数。RGBQUAD的结构如下:typedef struct tagRGBQUAD BYTE rgbBlue; BYTE rgbGreen; BYTE rgbRed; BYTE rgbReserved; RGBQUAD; 因此要得到调色板的总大小,可以用(颜色数*RGBQUAD 结构),其中颜色数被记录在BITM
9、APINFOHEADER 文件信息头中的 biClrUsed。得到颜色数:DWORD clrnum=(LPBITMAPINFOHEADER)pDIB)-biClrUsed;6.3得到DIB数据地址由图像数据指针=DIB指针+文件信息头大小(*(LPDWORD)pDIB)+调色板大小(颜色数*RGBQUAD结构):pbmpData=pDIB+*(LPDWORD)pDIB+(WORD)(clrnum*sizeof(RGBQUAD);7显示图像显示图像要用到的函数:int StretchDIBits( HDC hdc, / DC 句柄int XDest, /设备中显示 X 方向开始位置int YDe
10、st, /设备中显示 Y 方向开始位置int nDestWidth, /设备中显示 X 方向宽度int nDestHeight, /设备中显示 X 方向高度int XSrc, /图像中显示 X 方向开始位置int YSrc, /图像中显示 Y 方向开始位置int nSrcWidth, /图像中显示 X 方向宽度int nSrcHeight, /图像中显示 Y 方向宽度CONST VOID *lpBits, / 指向图像数据的指针CONST BITMAPINFO *lpBitsInfo, / 指向图像信息头的指针UINT iUsage, /DIB_PAL_COLORS 或者 DIB_RGB_CO
11、LORSDWORD dwRop / SRCCOPY);由该函数所用到的参数可知多数的参数我们已知,UINT iUsage提供了两种选择:DIB_PAL_COLORS或者DIB_RGB_COLORS分别表示绘图时使用用户提供的调色板还是图像中自已的调色板。7.1使用图像中自己的调色板:CDC *pDC=this-GetDC();:StretchDIBits(pDC-m_hDC,0,0,512,512,0,0,512,512,pbmpData,pbmpinfo,DIB_RGB_COLORS,SRCCOPY);即可。7.2使用用户定义的调色板7.2.1 创建调色板,步骤:创建逻辑调色板逻辑调色板的结
12、构:typedef struct tagLOGPALETTE WORD palVersion; /版本号WORD palNumEntries; /颜色数PALETTEENTRY palPalEntry1; /颜色数据指针 LOGPALETTE; LPLOGPALETTE lpPal=NULL;/逻辑调色板指针HANDLE Logpal=:GlobalAlloc(GHND,sizeof(LPLOGPALETTE)+sizeof(PALETTEENTRY)*clrnum);定义一个逻辑调色板的句柄,并为逻辑调色板分配空间。如果分配内存成功,获得内存地址指针,填充逻辑调色板if (hLogpal!=
13、0)lpPal=(LPLOGPALETTE):GlobalLock(HGLOBAL)hLogpal);:GlobalUnlock(hLogpal);lpPal-palVersion=PALVERSION;lpPal-palNumEntries=(WORD)clrnum;填充逻辑调色板颜色信息,这里将DIB自带的调色板读到逻辑调色板中:for (int i=0;ipalPalEntryi.peRed=pbmpinfo-bmiColorsi.rgbRed;lpPal-palPalEntryi.peGreen=pbmpinfo-bmiColorsi.rgbGreen;lpPal-palPalEntr
14、yi.peBlue=pbmpinfo-bmiColorsi.rgbBlue;lpPal-palPalEntryi.peFlags=0;pbmpinfo是BITMAPINFO对象,其结构前面已经给出。定义调色板对象,并调用其CreatePalette方法,以逻辑调色板指针为参数,创建调色板CPalette *pal=new CPalette;pal-CreatePalette(lpPal);7.2.2得到调色板句柄HPALETTE hPal=(HPALETTE)pal-m_hObject;7.2.3为即将绘图的DC选入刚创建的调色板:SelectPalette(pDC-m_hDC,hPal,TRUE);7.2.4:SetStretchBltMode(pDC-m_hDC, COLORONCOLOR);设置StretchBlt模式7.2.5绘图::StretchDIBits(pDC-m_hDC,0,0,512,512,0,0,512,512,pbmpData,pbmpinfo,DIB_PAL_COLORS,SRCCOPY);