如何遍历位图像素

时间:2019-07-17 14:25:02

标签: 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);

    }
}

1 个答案:

答案 0 :(得分:1)

  

如何遍历位图像素

使用 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);