我们正在尝试开发一种解决方案,即需要远程监视Windows XP计算机的桌面屏幕。屏幕捕获后无法访问缓冲区数据
根据我们的经验,我们发现基于GDI的方法比DirectX前端缓冲区捕获更快。
在GDI中,我们正在获取屏幕的句柄,如下所示。
// Get the Desktop windows handle and device context
hDesktopWnd=GetDesktopWindow();
hDesktopDC=GetDC(hDesktopWnd);
// Get the handle to the existing DC and create a bitmap file object
HDC hBmpFileDC=CreateCompatibleDC(hDesktopDC);
HBITMAP hBmpFileBitmap=CreateCompatibleBitmap(hDesktopDC,nWidth,nHeight);
// Assign the object in Memory DC to the bitmap and perform a bitblt
SelectObject(hBmpFileDC,hBmpFileBitmap);
BitBlt(hBmpFileDC,0,0,nWidth,nHeight,hDesktopDC,0,0,SRCCOPY|CAPTUREBLT);
// Assign the bitmap handle to a CImage Object
CImage m_temp;
m_temp.Attach(hBmpFileBitmap);
m_temp.Save("d:\\Images\\Image10.bmp");
该操作保存在给定的路径,这意味着该对象实际上保持从屏幕上的数据的硬盘驱动器上的m_temp的CImage对象。但在我的应用程序中,我想处理桌面缓冲区中的图像,我需要图像数据缓冲区指针。但是当我调用可以返回数据指针的函数m_temp.GetBits()时,我在那里得到NULL指针。 (I可以看到m_temp保持正确的高度,宽度,位/像素数据valiues但图像数据缓冲器指针为NULL)
即使是功能类似于
BITMAP bitmap;
GetObject(hBmpFileBitmap, sizeof(BITMAP), &bitmap);
BYTE *pucInputImage = (BYTE*) bitmap.bmBits; -> Returns NULL
或者
BYTE* pucImage = NULL;
GetBitmapBits(hBmpFileBitmap,nWidth*nHeight*4,(LPVOID)pucImage);
也在变量pucImage中返回NULL。这是工作的唯一的事情是
pBuf=malloc(bmpInfo.bmiHeader.biSizeImage)
GetDIBits(hdc,hBitmap,0,bmpInfo.bmiHeader.biHeight,pBuf,&bmpInfo,DIB_RGB_COLORS);
在这里,我们需要通过PBUF变量(与图像的大小预分配)和复制的GetDIBits从数据bitmpa处理到这个PBUF缓冲区。这需要额外15毫秒。
据我所知,在bitblt操作过程中发生数据传输,我觉得我应该能够避免这种额外的数据传输,避免每帧15ms的延迟。
我想到的另一件事是因为桌面窗口需要被用户写保护,并且HDC hBmpFileDC是从DesktopDC派生的,它可能会继承原始DC的写保护属性。如果是这样的话,是有一些方法来这里纪念这个写保护关闭新创建的变量(如下图所示)
HDC hBmpFileDC=CreateCompatibleDC(hDesktopDC);
HBITMAP hBmpFileBitmap=CreateCompatibleBitmap(hDesktopDC,nWidth,nHeight);