抓屏中 GetDIBits函数 的问题

TrueZq 2003-05-30 09:08:44
定时(如1秒)抓取屏幕图象并保存在硬盘上,
开始抓屏后,匀速缓慢移动鼠标,会发现在保存位图时
鼠标有明显的停滞,跟踪后发现是API函数GetDIBits的问题
如何解决?
或者不用GetDIBits,怎样从HBITMAP中取出数据拷贝到内存区域?

保存BMP代码如下:
BOOL CScrCaptureDlg::SaveBmp(HBITMAP hBitmap, CFile& file)
{
if (hBitmap == NULL)
return FALSE;
HDC hDC;
int iBits;
//当前显示分辨率下每个像素所占字节数
WORD wBitCount;
//位图中每个像素所占字节数
//定义调色板大小, 位图中像素字节大小 ,
//位图大小
DWORD dwPaletteSize=0, dwBmBitsSize, dwDIBSize;
BITMAP Bitmap;
HANDLE hDib;
HPALETTE hPal,hOldPal=NULL;
//位图属性结构

BITMAPFILEHEADER bmfHdr; // Header for Bitmap file
LPBITMAPINFOHEADER lpBI; // Pointer to DIB info structure
BITMAPINFOHEADER bi;
//位图信息头结构

//DWORD dwDIBSize;
//计算位图文件每个像素所占字节数
hDC = CreateDC("DISPLAY",NULL,NULL,NULL);
iBits = GetDeviceCaps(hDC, BITSPIXEL) *
GetDeviceCaps(hDC, PLANES);
DeleteDC(hDC);
if (iBits<=1)
wBitCount=1;
else if (iBits<=4)
wBitCount=4;
else if (iBits<=8)
wBitCount=8;
else if (iBits<=16)
wBitCount=16;
else if (iBits<=24)
wBitCount=24;
//计算调色板大小
if (wBitCount<=8)
dwPaletteSize=(1<<wBitCount) *
sizeof(RGBQUAD);
GetObject(hBitmap, sizeof(BITMAP), (LPSTR)&Bitmap);
bi.biSize= sizeof(BITMAPINFOHEADER);
bi.biWidth= Bitmap.bmWidth;
bi.biHeight= Bitmap.bmHeight;
bi.biPlanes= 1;
bi.biBitCount= wBitCount;
bi.biCompression= BI_RGB;
bi.biSizeImage= 0;
bi.biXPelsPerMeter= 0;
bi.biYPelsPerMeter= 0;
bi.biClrUsed= 0;
bi.biClrImportant= 0;

dwBmBitsSize=((Bitmap.bmWidth *
wBitCount+31)/32)* 4
*Bitmap.bmHeight ;
hDib=GlobalAlloc(GHND,dwBmBitsSize+
dwPaletteSize+sizeof(BITMAPINFOHEADER));
lpBI=(LPBITMAPINFOHEADER)GlobalLock(hDib);
*lpBI=bi;
// 处理调色板
hPal=(HPALETTE)GetStockObject(DEFAULT_PALETTE);
if (hPal)
{
//hDC=GetDC(NULL);
hDC=::GetDC(this->m_hWnd);
hOldPal=(HPALETTE)SelectPalette(hDC,hPal,FALSE);
RealizePalette(hDC);
}

// 获取该调色板下新的像素值
//下句的问题!!!!!
GetDIBits(hDC, hBitmap, 0, (UINT) Bitmap.bmHeight,
(LPSTR)lpBI+sizeof(BITMAPINFOHEADER)
+dwPaletteSize,(BITMAPINFO*)
lpBI, DIB_RGB_COLORS);
//恢复调色板
if (hOldPal)
{
SelectPalette(hDC,hOldPal, TRUE);
RealizePalette(hDC);
//ReleaseDC(NULL, hDC);
::ReleaseDC(this->m_hWnd , hDC);
}

/*
* Fill in the fields of the file header
*/

/* Fill in file type (first 2 bytes must be "BM" for a bitmap) */
bmfHdr.bfType = 0x4d42; // "BM"
dwDIBSize = sizeof(BITMAPINFOHEADER)
+ dwPaletteSize + dwBmBitsSize;
bmfHdr.bfSize = dwDIBSize+sizeof(BITMAPFILEHEADER);
bmfHdr.bfReserved1 = 0;
bmfHdr.bfReserved2 = 0;
bmfHdr.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER)
+ (DWORD)sizeof(BITMAPINFOHEADER)
+ dwPaletteSize;

TRY
{
// Write the file header
file.Write((LPSTR)&bmfHdr, sizeof(BITMAPFILEHEADER));
//
// Write the DIB header and the bits
//
file.WriteHuge((LPSTR)lpBI, dwDIBSize);
}
CATCH (CFileException, e)
{
::GlobalUnlock((HGLOBAL) hDib);
THROW_LAST();
}
END_CATCH

::GlobalUnlock((HGLOBAL) hDib);
return TRUE;

}

...全文
93 1 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
1 条回复
切换为时间正序
请发表友善的回复…
发表回复
myjesky 2003-05-30
  • 打赏
  • 举报
回复
你的位图不可能是32位吗

19,471

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 图形处理/算法
社区管理员
  • 图形处理/算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧