位图信息头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;
这个结构的长度是固定的,为40个字节(LONG为32位整数),各个域的说明如下: biSize 指定这个结构的长度,为40。 biWidth 指定图象的宽度,单位是象素。 biHeight 指定图象的高度,单位是象素。 biPlanes 必须是1,不用考虑。 biBitCount 指定表示颜色时要用到的位数,常用的值为1(黑白二色图), 4(16色图), 8(256色), 24(真彩色图)(新的.bmp格式支持32位色,这里就不做讨论了)。 biCompression 指定位图是否压缩,有效的值为BI_RGB,BI_RLE8,BI_RLE4,BI_BITFIELDS(都是一些Windows定义好的常量)。要说明的是,Windows位图可以采用RLE4,和RLE8的压缩格式,但用的不多。我们今后所讨论的只有第一种不压缩的情况,即biCompression为BI_RGB的情况。 biSizeImage 指定实际的位图数据占用的字节数,其实也可以从以下的公式中计算出来: biSizeImage=biWidth’ × biHeight 要注意的是:上述公式中的biWidth’必须是4的整倍数(所以不是biWidth,而是biWidth’,表示大于或等于biWidth的,最接近4的整倍数。举个例子,如果biWidth=240,则biWidth’=240;如果biWidth=241,biWidth’=244)。如果biCompression为BI_RGB,则该项可能为零 biXPelsPerMeter 指定目标设备的水平分辨率,单位是每米的象素个数,关于分辨率的概念。 biYPelsPerMeter 指定目标设备的垂直分辨率,单位同上。 biClrUsed 指定本图象实际用到的颜色数,如果该值为零,则用到的颜色数为2biBitCount。 biClrImportant 指定本图象中重要的颜色数,如果该值为零,则认为所有的颜色都是重要的。
一般作为CreateDIBSection函数的第二个参数,CreateDIBSection函数如下:
HBITMAP CreateDIBSection(HDC hdc,CONST BITMAPINFO *pbmi,UINT iUsage,VOID** ppvBits,HANDLE hSection,DWORD dwOffset);
参数:
hdc:设备环境句柄。如果iUsage的值是DIB_PAL_COLORS,那么函数使用该设备环境的逻辑调色板对与设备无关位图的颜色进行初始化。
pbmi:指向BITMAPINFO结构的指针,该结构指定了与设备无关位图的各种属性,其中包括位图的维数和颜色。
iUsage:指定由pbmi参数指定的BITMAPINFO结构中的成员bmiColors数组包含的数据类型(要么是逻辑调色板索引值,要么是原文的RGB值)。下列值是系统定义的,其含义为:
DIB_PAL_COLORS:表示成员bmiColors是hdc指定的设备环境的逻辑调色板,使用的是16位索引值数组。
DIB_RGB_COLORS:表示结构BITMAPINFO中包含了RGB值的数组。
ppvBits:指向一个变量的指针,该变量接收一个指向DIB位数据值的指针。
hSection:文件映射对象的句柄。函数将使用该对象来创建DIB(与设备无关位图)。该参数可以是NULL。
如果hSection不是NULL,那么它一定是文件映射对象的句柄。该对象是通过调用带有PAGE_READWRITE或PAGE_WRITECOPY标志的CreateFileMapping函数创建的。不支持只读的DIB类型。通过其他方法创建的句柄将会引起CreateDIBSection函数执行失败。
如果hSection不是NULL,那么函数CreateDIBSection将在hSection引用的文件映射对象中偏移量为dwOffset处获取位图的位数据值。应用程序可以在以后通过调用GetObject函数来检索hSection句柄,其中GetObject函数使用了GreateDIBSection函数返回的GBITMAP类型的对象。
如果hSection为NULL,那么系统将为与设备无关位图(DIB)分配内存。在这种情况下,函数CreateDIBSection将忽略参数dwOffset,应用程序无法在以后获取指向内存的句柄。通过调用GetObject函数来填充的DIBSECTION结构成员dshSection也将成为NULL。
DwOffset:指定从hSection引用的文件映射对象开始处算起的偏移量,超过这个偏移量的地方就是位图的位数据值开始存放的地方。在hSection为NULL时忽略该值。位图的位数据值是以DWORD为单位计算的。
返回值:如果函数执行成功,那么返回值是一个指向刚刚创建的与设备无关位图的句柄,并且*ppvBits指向该位图的位数据值;如果函数执行失败,那么返回值为NULL,并且*ppvBit也为NULL,若想获得更多错误信息,请调用GetLastError函数。
示例:
HDC hTempDC = ::CreateCompatibleDC(hDestDC);
if (NULL == hTempDC)
return;
//Creates Source DIB
LPBITMAPINFO lpbiSrc;
// Fill in the BITMAPINFOHEADER
lpbiSrc = (LPBITMAPINFO) new BYTE[sizeof(BITMAPINFOHEADER)];
lpbiSrc->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
lpbiSrc->bmiHeader.biWidth = dwWidth;
lpbiSrc->bmiHeader.biHeight = dwHeight;
lpbiSrc->bmiHeader.biPlanes = 1;
lpbiSrc->bmiHeader.biBitCount = 32;
lpbiSrc->bmiHeader.biCompression = BI_RGB;
lpbiSrc->bmiHeader.biSizeImage = dwWidth * dwHeight;
lpbiSrc->bmiHeader.biXPelsPerMeter = 0;
lpbiSrc->bmiHeader.biYPelsPerMeter = 0;
lpbiSrc->bmiHeader.biClrUsed = 0;
lpbiSrc->bmiHeader.biClrImportant = 0;
COLORREF* pSrcBits = NULL;
//创建应用程序可以直接写入的、与设备无关的位图(DIB)
HBITMAP hSrcDib = CreateDIBSection (
hSrcDC, lpbiSrc, DIB_RGB_COLORS, (void **)&pSrcBits,
NULL, NULL);
if ((NULL != hSrcDib) && (NULL != pSrcBits))
{
HBITMAP hOldTempBmp = (HBITMAP)::SelectObject (hTempDC, hSrcDib);
.................
.................
}