c++ - 如何迭代位图像素

标签 c++ bitmap pixel

我正在尝试读取屏幕的某些区域并遍历该区域,如果某个红点穿过该区域,请单击鼠标左键。我想我已经接近解决我的问题了,但是我搜索了很多,但没有找到任何解决方案。另外,如果我的代码有问题,请告诉我,因为我正在尝试使用位图,但我对此了解不多。

这是我的问题的图像表示(我没有 10 名代表来发布图像):

enter image description here

只需要读取绿色区域。

int main()
{
    LPCWSTR windowTitle = L"window_name";
    HWND hwnd = FindWindow(NULL, windowTitle);

    HDC hdcSource, hdcMemory;
    BYTE* bitPointer;
    POINT cursorPosition;
    int red, green, blue;
    int x = 140;
    int y = 205;
    int width = 1920 - 1760;
    int height = 1080 - 875;

    while (true)
    {
        int width = 1920 - 1760;
        int height = 1080 - 875;

        hdcSource = GetDC(hwnd);
        hdcMemory = CreateCompatibleDC(hdcSource);

        int capX = GetDeviceCaps(hdcSource, HORZRES);
        int capY = GetDeviceCaps(hdcSource, VERTRES);

        HBITMAP hBitmap = CreateCompatibleBitmap(hdcSource, width, height);
        HBITMAP hBitmapOld = (HBITMAP)SelectObject(hdcMemory, hBitmap);

        BitBlt(hdcMemory, 0, 0, width, height, hdcSource, x, y, SRCCOPY);
        hBitmap = (HBITMAP)SelectObject(hdcMemory, hBitmapOld);

        // Loop through bitmap selection and if find the RGB color (220, 0 , 0) click with left mouse button
        for (int i = 0; ???; i++)
        {
            // something here

            if (red == 220 && green == 0 && blue == 0)
            {
                GetCursorPos(&cursorPosition);
                mouse_event(MOUSEEVENTF_LEFTDOWN, cursorPosition.x, cursorPosition.y, 0, 0);
                mouse_event(MOUSEEVENTF_LEFTUP, cursorPosition.x, cursorPosition.y, 0, 0);
            }
        }

        ReleaseDC(NULL, hdcSource);
        ReleaseDC(NULL, hdcMemory);

    }
}

最佳答案

How to iterate through bitmap pixels

使用DIB部分直接快速访问像素

例如,此测试将记事本中的所有白色像素替换为绿色像素 =>

enter image description here

(结果复制到屏幕进行测试)

        HDC hDCScreen = GetDC(NULL);
        HWND hWndDest = FindWindow(L"Notepad", NULL);
        if (hWndDest)
        {
            if (IsIconic(hWndDest))
            {
                ShowWindow(hWndDest, SW_RESTORE);
                Sleep(100);
            }
            RECT rect;
            GetWindowRect(hWndDest, &rect);
            int nWidth = rect.right - rect.left;
            int nHeight = rect.bottom - rect.top;

            HDC hDC = GetDC(hWndDest);
            HDC hCaptureDC = CreateCompatibleDC(hDCScreen);
            HBITMAP hCaptureBitmap = CreateCompatibleBitmap(hDCScreen, nWidth, nHeight);
            HGDIOBJ hOldBitmap = SelectObject(hCaptureDC, hCaptureBitmap);
            PrintWindow(hWndDest, hCaptureDC, PW_RENDERFULLCONTENT);
            HDC hDCMem = CreateCompatibleDC(hDC);
            HBITMAP hBitmapOld;
            BITMAPINFO bi = { 0 };
            bi.bmiHeader.biSize = sizeof(bi.bmiHeader);
            bi.bmiHeader.biWidth = nWidth;
            bi.bmiHeader.biHeight = nHeight;
            bi.bmiHeader.biPlanes = 1;
            bi.bmiHeader.biBitCount = 32;
            bi.bmiHeader.biCompression = BI_RGB;
            BYTE *pbBitmap;
            HBITMAP hBitmap = CreateDIBSection(hDCMem, &bi, DIB_RGB_COLORS, (void**)&pbBitmap, NULL, 0);
            if (hBitmap)
            {
                hBitmapOld = (HBITMAP)SelectObject(hDCMem, hBitmap);
                BitBlt(hDCMem, 0, 0, nWidth, nHeight, hCaptureDC, 0, 0, SRCCOPY);

                RGBQUAD *pRGB;
                LONG nPixels;
                for (pRGB = (RGBQUAD *)pbBitmap, nPixels = nWidth * nHeight; nPixels > 0; ++pRGB, --nPixels)
                {
                    ULONG nRed = pRGB->rgbRed;
                    ULONG nGreen = pRGB->rgbGreen;
                    ULONG nBlue = pRGB->rgbBlue;

                    if (nRed == 255 && nGreen == 255 && nBlue == 255)
                    {
                        pRGB->rgbRed = 0;
                        pRGB->rgbGreen = 255;
                        pRGB->rgbBlue = 0;
                    }
                }
                // Test copy to screen
                BitBlt(hDCScreen, 0, 0, nWidth, nHeight, hDCMem, 0, 0, SRCCOPY);
                SelectObject(hDCMem, hBitmapOld);
                DeleteObject(hBitmap);
            }
            DeleteDC(hDCMem);

            hOldBitmap = SelectObject(hCaptureDC, hOldBitmap);
            DeleteDC(hCaptureDC);
            DeleteObject(hCaptureBitmap);
            ReleaseDC(hWndDest, hDC);               
        }
        ReleaseDC(NULL, hDCScreen);

关于c++ - 如何迭代位图像素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57078206/

相关文章:

c++ - 返回常量引用参数而不复制

bitmap - 将指纹位图转换为 ISO/IEC 19794-2 模板

android - ListView 中的位图 : Loading slowly

c++ - 如何知道程序调用了库的哪些函数

java - std::vector 和 java.util.Vector 之间的差异

c# - 如何更改我的 C++ 代码以用作 C# 中的 DLL?

actionscript-3 - BitmapData类的threshold方法中mask参数有什么作用?

c++ - SDL 不渲染像素

android - 如何以编程方式查找 Android 中的坏点

r - 如何使用R从图像中获取像素数据