0

こんにちはみんな私は次のコードを持っています:

#define ScreenXResolution GetDeviceCaps(GetDC(0), HORZRES)
#define ScreenYResolution GetDeviceCaps(GetDC(0), VERTRES)

BYTE *screenData = malloc(sizeof(BYTE) * (3 * ScreenXResolution * ScreenYResolution));
captureScreenshot(&screenData);

void captureScreenshot(BYTE *screenData)
{
    HDC hdc = GetDC(NULL), hdcMem = CreateCompatibleDC(hdc);
    HBITMAP hBitmap = CreateCompatibleBitmap(hdc, ScreenXResolution, ScreenYResolution);
    BITMAPINFOHEADER bmi = {0};
    bmi.biSize = sizeof(BITMAPINFOHEADER);
    bmi.biPlanes = 1;
    bmi.biBitCount = 24;
    bmi.biWidth = ScreenXResolution;
    bmi.biHeight = -ScreenYResolution;
    bmi.biCompression = BI_RGB;
    SelectObject(hdcMem, hBitmap);
    BitBlt(hdcMem, 0, 0, ScreenXResolution, ScreenYResolution, hdc, 0, 0, SRCCOPY);
    GetDIBits(hdc, hBitmap, 0, ScreenYResolution, screenData, (BITMAPINFO*)&bmi, DIB_RGB_COLORS);
    DeleteObject(hBitmap);
    DeleteDC(hdcMem);
    ReleaseDC(NULL, hdc);
}

私が達成しようとしているのは、画面のスクリーンショットを撮り、それを screenData に入れることです。

それが必要な理由は、どの位置にある特定の RGB カラーであるかを確認できるようにするためですが、そうするのに問題があります。

誰かが私を助けることができれば、それは大歓迎です。

ありがとう!

編集: メモリ割り当てを追加しました。RGB を取得しようとする方法は、次のような colorref を返す関数によるものです。

COLORREF getRGBFromScreenshot(BYTE *screenshot, int x, int y)
{
    return RGB(screenshot[3 * ((y * ScreenXResolution) + x) + 2], screenshot[3 * ((y * ScreenXResolution) + x) + 1], screenshot[3 * ((y * ScreenXResolution) + x)]);
}
4

2 に答える 2

3

1 つ、おそらく 2 つの問題があります。

1 つ目は、引数をポインターのアドレスとして渡すことですBYTE **。ただし、これは単一のポインターとしてのみ使用します。これは、電話をかけるGetDIBitsと、間違ったアドレスに入力されることを意味します。コンパイラによってこれに関する警告が表示されるはずです。

2 番目の問題は、表示されていないコードが存在する可能性があるため、より潜在的ですが、screenDataポインターを初期化しないことです。ビットマップデータをコピーするためのメモリを割り当てていないようです。

上記の問題は両方とも未定義の動作につながり、動作しているように見えても正しく動作しないか、いつでもクラッシュする可能性があります。


ポインターの問題に関しては、ポインターはまさにその名前が示すとおりです。つまり、何かを指します。ポインターの場合、次のscreenDataように視覚化できます。

+------------+ +---------------------------------+
| | スクリーンデータ | ---> | screenData に割り当てられたメモリ |
+------------+ +---------------------------------+

&ただし、の呼び出しでaddress-of 演算子を使用すると、変数captureScreenshotへの新しいポインターが作成されます。screenData

+-------------+ +------------+ +-------------------- --------------+
| | &screenData | ---> | スクリーンデータ | ---> | screenData に割り当てられたメモリ |
+-------------+ +------------+ +-------------------- --------------+

上記の単純な「写真」から、使用が機能しない理由は簡単にわかり&screenDataます。単にまったく別のメモリ位置を指しているだけです。

于 2013-03-31T00:36:36.883 に答える
0

@Joachim Pilborg が指摘しscreenDataているように、適切なサイズのバッファを事前に割り当てる必要があります。screenDataが null の場合GetDIBits()、BITMAPINFO 構造体のみを埋めます (こちらを参照)。が割り当てられていない場合screenData、メモリのランダムな部分を指している可能性があり、これによりクラッシュが発生することがよくあります。

いずれにせよ、コードは からの戻り値をチェックして、GetDIBits()何が起こっているかを調べる必要があります。

于 2013-03-31T00:38:57.360 に答える