C++-windows7下无法正常使用GetDIBits获取整个屏幕的截图,但XP是可以的,求指点

发布于 2016-10-09 15:29:53 字数 1185 浏览 1158 评论 1

    LPBITMAPINFO ptBmi;
HWND DeskHwnd;
HDC DeskHDC,ComHDC;
HBITMAP hBmp = 0;
int sdwRet;

BITMAPINFO infoHeader;
memset(&infoHeader.bmiHeader, 0, sizeof(BITMAPINFOHEADER));
infoHeader.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
infoHeader.bmiHeader.biWidth = x;
infoHeader.bmiHeader.biHeight = -y;
infoHeader.bmiHeader.biPlanes = 1;
infoHeader.bmiHeader.biBitCount = 32;
infoHeader.bmiHeader.biCompression = BI_RGB;

/* 如果图像没有分配 */
if (pImg->imageData == NULL)
{
char *data = new char[x * y * pImg->nChannels];
cvSetData(pImg, data, pImg->widthStep);
}

//获取桌面窗口句柄
//DeskHwnd = GetDesktopWindow();
//获取桌面窗口DC
//DeskHDC = GetWindowDC(DeskHwnd);
//ComHDC = CreateCompatibleDC(DeskHDC);
DeskHDC = ::GetDC(0);
hBmp = (HBITMAP)GetCurrentObject(DeskHDC, 7);

sdwRet = GetDIBits(DeskHDC, hBmp, 0, y,
pImg->imageData, &infoHeader,
DIB_RGB_COLORS);

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

灵芸 2017-03-26 04:14:59

首先,你的代码中有几个小问题:
你的cvSetData函数用途不明,对于截屏这个目的来说应该没有用处。
计算所需内存的表达式x * y * pImg->nChannels,明显是错误的。Bmp格式要求每行扫描线的数据对齐到4个字节,应该不是你这里的计算方式。
infoHeader.bmiHeader.biBitCount = 32;比较浪费空间,建议改成24(实际效果是一样的)。
GetCurrentObject(DeskHDC, 7);为什么不用OBJ_BITMAP?
最后,你的调用方式并不符合MSDN中的规范,XP下刚好能工作,并不等于这就是正确的。给你一个我自己用的截屏函数作为例子吧:

struct BmpHead : public BITMAPINFOHEADER
{
BmpHead(int x, int y, WORD bits = 24);
BITMAPINFO * operator & () {return (BITMAPINFO*)this;}
};

BmpHead::BmpHead(int x, int y, WORD bits)
{
biSize = sizeof(BITMAPINFOHEADER);
biWidth = x;
biHeight = y;
biPlanes = 1;
biBitCount = bits;
biCompression = BI_RGB;
int LineBytes = ((x * biBitCount + 31) & -32) >> 3;
biSizeImage = LineBytes * y;

biXPelsPerMeter = biYPelsPerMeter = 0;
biClrUsed = biClrImportant = 0;
}

void *WINAPI TakeScreenShot(const RECT &rect, HWND hWnd = NULL)
{
HDC hdcWnd = NULL;
HDC hdcCap = NULL;
HBITMAP bmpCap = NULL;
void *pData = NULL;
do
{
int x = rect.right - rect.left;
int y = rect.bottom - rect.top;
BmpHead bmi(x, y);

hdcWnd = ::GetDC(hWnd);
if (hdcWnd == NULL) break;
hdcCap = ::CreateCompatibleDC(hdcWnd);
if (hdcCap == NULL) break;
bmpCap = ::CreateCompatibleBitmap(hdcWnd, x, y);
if (bmpCap == NULL) break;

HGDIOBJ bmOld = ::SelectObject(hdcCap, bmpCap);
if (bmOld == NULL) break;
BOOL bSuccess = ::BitBlt(hdcCap, 0, 0, x, y,
hdcWnd, rect.left, rect.top, SRCCOPY);
::SelectObject(hdcCap, bmOld);
if (!bSuccess) break;

pData = malloc(bmi.biSizeImage);
if (pData == NULL) break;

DWORD dwRet = ::GetDIBits(hdcWnd, bmpCap, 0, y,
pData, &bmi, DIB_RGB_COLORS);
if (dwRet == 0)
{
free(pData);
pData = NULL;
}
}while(false);

if (hdcCap != NULL) ::DeleteDC(hdcCap);
if (bmpCap != NULL) ::DeleteObject(bmpCap);
if (hdcWnd != NULL) ::ReleaseDC(hWnd, hdcWnd);
return pData;
}

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文