在屏幕上查找图像

时间:2019-04-28 17:49:43

标签: c++ winapi

我想知道如何解决这个问题。我想每隔X秒检查一次屏幕是否包含图像(例如红点),如果是,则返回True。我对Python非常熟悉,并且那里有一些简单的解决方案。但是我还没有找到类似的解决方案。

我基本上想做的是:

  1. 拍摄屏幕截图
  2. 在屏幕截图上找到图像X
  3. 退货

研究了OpenCV,可以用这种方法解决它,但是可能有点过分扩展了。我正在考虑getPixel遍历屏幕中的所有像素。但这非常慢。

#include <Windows.h>
#include <iostream>

using namespace std;

int main()
{
    HWND runelite = GetForegroundWindow();
    HMONITOR monitor = MonitorFromWindow(runelite, MONITOR_DEFAULTTONEAREST);
    MONITORINFO info;
    info.cbSize = sizeof(MONITORINFO);
    GetMonitorInfo(monitor, &info);
    int monitor_width = info.rcMonitor.right - info.rcMonitor.left;
    int monitor_height = info.rcMonitor.bottom - info.rcMonitor.top;

    int r, g, b;

    HDC screenshot = GetDC(NULL); 

    for (int i = 0; i < monitor_height; i++) {
        for (int j = 0; j < monitor_width; j++) {
            DWORD color = GetPixel(screenshot, j, i);
            cout << "Scanning -> X: " << j << " Y: " << i << endl;
            r = GetRValue(color);
            g = GetGValue(color);
            b = GetBValue(color);
            if (r == 0 && g == 0 && b == 0) {
                cout << "Button found by color!" << endl;
                goto end;
            }
        }
    }

    end:
    ReleaseDC(NULL, screenshot);
    return 0;
}

1 个答案:

答案 0 :(得分:3)

如果将HDC的内容复制到另一个位图并获取指向图像数据的指针并对其进行循环,则可以大大提高速度。

创建内存位图

HDC memDC = CreateCompatibleDC ( hDC );
HBITMAP memBM = CreateCompatibleBitmap ( hDC, nWidth, nHeight );
SelectObject ( memDC, memBM );

然后通过BitBlt将屏幕数据比特化到该位图,并使用GetDIBits获得位图数据。

还请注意,GetDC(NULL)不会截屏,但可以访问Windows Live主HDC。绘图直接在桌面上进行。 那就是为什么每个GetPixel都需要很长的时间。