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 ポインタが取得されます。(正しい高さ、幅、ビット/ピクセル データ値を保持している m_temp を確認できますが、画像データ バッファー ポインターは 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 操作中にデータ転送が発生していますが、フレームごとに 15 ミリ秒の遅延を回避して、この余分なデータ転送を回避できるはずだと感じています。
私の頭に浮かぶもう1つのことは、デスクトップウィンドウをユーザーから書き込み保護する必要があり、HDC hBmpFileDCがDesktopDCから派生しているためです。元のDCの書き込み保護プロパティを継承している可能性があります. この場合、新しく作成された変数に対してこの書き込み保護をオフにする方法はありますか (以下を参照)。
HDC hBmpFileDC=CreateCompatibleDC(hDesktopDC);
HBITMAP hBmpFileBitmap=CreateCompatibleBitmap(hDesktopDC,nWidth,nHeight);