网上关于设备上下文获取位图句柄,然后操作位图句柄保存位图文件的帖子不少,不过通过已知的bitmapinfo(address of bitmap data)和bitmap的数据信息lpBits(address of bitmap bits)来获取位图文件的例子几乎没有。最近因为要HOOKstretchdibits这个api函数,但参数信息中没有源设备上下文,也就得不到源位图句柄,后来测试发现bitmapinfo里面的确有源位图的一些信息:位图信息头和调色板的信息,另外的lpBits也有位图的位信息。那么如何来通过这两个获取位图文件呢。通过查资料设备独立位图(dib)有四部分构成:位图文件头,位图信息头,调色板信息,位图的位数据。然后发现bitmapinfo包括位图信息头和调色板信息,而lpBits拥有位图位数据信息,那么我们只要构建一个位图文件头,然后将四部分分别写入文件保存,岂不是ok了呢,经测试上面想法可行,代码如下:
int num=lpBitsInfo->bmiHeader.biWidth;
HANDLE fh, hDib;//, hPal
WORD wBitCount;
//位图文件头
BITMAPFILEHEADER bmfHdr;
DWORD dwPaletteSize=0,dwBmBitsSize,dwDIBSize, dwWritten;
LPBITMAPINFOHEADER lpbi;
wBitCount=lpBitsInfo->bmiHeader.biBitCount;//每个像素位数
PutDIBInfroToFile("c://myStretchDIBits.txt","/r/n wBitCount=%d length=%d XDest=%d YDest=%d nDestWidth=%d nDestHeight=%d XSrc=%d YSrc=%d nSrcWidth=%d,nSrcHeight=%d",
wBitCount,num,XDest,YDest,nDestWidth,nDestHeight,XSrc,YSrc,nSrcWidth,nSrcHeight);//将相关信息写入文本文件中
dwBmBitsSize = ((lpBitsInfo->bmiHeader.biWidth*wBitCount+31)/32)*4*lpBitsInfo->bmiHeader.biHeight;//位图信息头大小;
dwPaletteSize=(1<<wBitCount)*sizeof(RGBQUAD);//调色板大小
hDib = GlobalAlloc(GHND,dwBmBitsSize+dwPaletteSize+sizeof(BITMAPINFOHEADER));
lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDib);
*lpbi = lpBitsInfo->bmiHeader;
fh=CreateFile("c://myStretchDIBits.bmp", GENERIC_WRITE,0, NULL, CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL);//创建位图文件句柄
if (fh==INVALID_HANDLE_VALUE)
return FALSE;
// 设置位图文件头
bmfHdr.bfType = 0x4D42; // "BM"
dwDIBSize=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+dwPaletteSize+dwBmBitsSize;
bmfHdr.bfSize = dwDIBSize;
bmfHdr.bfReserved1 = 0;
bmfHdr.bfReserved2 = 0;
bmfHdr.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER)+(DWORD)sizeof(BITMAPINFOHEADER)+dwPaletteSize;
// 写入位图文件头
WriteFile(fh, (LPSTR)&bmfHdr, sizeof(BITMAPFILEHEADER), &dwWritten, NULL);
// 写入位图文件其余内容
WriteFile(fh, (LPSTR)lpbi, sizeof(BITMAPINFOHEADER)+dwPaletteSize , &dwWritten, NULL);
WriteFile(fh, (LPSTR)lpBits, dwBmBitsSize , &dwWritten, NULL);
//清除
GlobalUnlock(hDib);
GlobalFree(hDib);
CloseHandle(fh);
位图抓取成功,但还有些小问题没有解决。