一、DIB内的位图基本上没有经过任何压缩。
DIB的扩展名是.BMP或者.DIB
与大多数位图格式不同的是,DIB从底部开始,水平向上扫描图片。
JPEG,GIF 是压缩后的DIB。
二、位图操作:
1,打开位图
hFile = CreateFile (pstrFileName, GENERIC_READ, FILE_SHARE_READ, NULL,
OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL) ;
2,读取位图
dwFileSize = GetFileSize (hFile, &dwHighSize) ;
pbmfh = malloc (dwFileSize) ;
ReadFile (hFile, pbmfh, dwFileSize, &dwBytesRead, NULL) ;
3,读取位图信息
static BITMAPINFO * pbmi ;
static BYTE * pBits ;
pbmi = (BITMAPINFO *) (pbmfh + 1) ;
pBits = (BYTE *) pbmfh + pbmfh->bfOffBits ;
if (pbmi->bmiHeader.biSize == sizeof (BITMAPCOREHEADER))
{
cxDib = ((BITMAPCOREHEADER *) pbmi)->bcWidth ;
cyDib = ((BITMAPCOREHEADER *) pbmi)->bcHeight ;
}
else
{
cxDib = pbmi->bmiHeader.biWidth ;
cyDib = abs (pbmi->bmiHeader.biHeight) ;
}
4,显示位图:
SetDIBitsToDevice (hdc,
100, // xDst
100, // yDst
cxDib, // cxSrc
cyDib, // cySrc
0, // xSrc
0, // ySrc
0, // first scan line
cyDib, // number of scan lines
pBits,
pbmi,
DIB_RGB_COLORS) ;
SetDIBitsToDevice没有掩码参数
如果位图过大,可以采取连续显示方法,就是每次读一行或几行,然后SetDIBitsToDevice显示出来,例子见seqdisp。
StretchDIBits (hdc, 0, 0, cxClient, cyClient,
0, 0, cxDib, cyDib,
pBits, pbmi, DIB_RGB_COLORS, SRCCOPY) ;
StretchDIBits和SetDIBitsToDevice的关系等同与Bitblt和StretchBlt的关系。但StretchDIBits有掩码参数。
另外StretchDIBits不能通过连续显示节省内存。
5,保存位图
hFile = CreateFile (pstrFileName, GENERIC_WRITE, 0, NULL,
CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL) ;
WriteFile (hFile, pbmfh, pbmfh->bfSize, &dwBytesWritten, NULL) ;
三、DIB和DDB转化
1,从DIB 到 DDB
1.1 如上面,用ReadFile打开DIB后,hBitmap = CreateDIBitmap (hdc, (BITMAPINFOHEADER *) (pbmfh + 1),CBM_INIT,
(BYTE *) pbmfh + pbmfh->bfOffBits,(BITMAPINFO *) (pbmfh + 1),DIB_RGB_COLORS) ;
如果CreateDIBitmap的时候没有初始化像素位,可以用SetDIBits
1.2 CreateDIBSection 创建位图的一部分:位图像素位的内存块 bits
创建的内存块归系统所有,传输速度快,能用指针直接改变DIB位。deleteobject(hbitmap)的时候系统自动释放内存块。
步骤:同上,读取pbmi后,
CreateDIBSection (NULL, pbmi, DIB_RGB_COLORS, &pBits, NULL, 0) ;
ReadFile (hFile, pBits, bmfh.bfSize - bmfh.bfOffBits, &dwBytesRead, NULL) ;
2 从DDB到DIB
GetDIBits
但此方法一般不用,因为如果有HBITMAP句柄的话,一定会有创建这个句柄的资源。而DDB包含的信息会比较少,所以不如直接从资源中保存。