C++ Getting RGB from hBitmap

前端 未结 2 1965
野趣味
野趣味 2021-02-06 07:27

Working with bitmaps is very new to me so I\'ve been really struggling with the online tutorials and strategies that I\'ve read through. Basically my goal is to scan the screen

2条回答
  •  野趣味
    野趣味 (楼主)
    2021-02-06 08:13

    The issue is that your screen is actually 32bits deep not 24. The code below will give you the result you need:

    /* Globals */
    int ScreenX = 0;
    int ScreenY = 0;
    BYTE* ScreenData = 0;
    
    void ScreenCap() 
    {
        HDC hScreen = GetDC(NULL);
        ScreenX = GetDeviceCaps(hScreen, HORZRES);
        ScreenY = GetDeviceCaps(hScreen, VERTRES);
    
        HDC hdcMem = CreateCompatibleDC(hScreen);
        HBITMAP hBitmap = CreateCompatibleBitmap(hScreen, ScreenX, ScreenY);
        HGDIOBJ hOld = SelectObject(hdcMem, hBitmap);
        BitBlt(hdcMem, 0, 0, ScreenX, ScreenY, hScreen, 0, 0, SRCCOPY);
        SelectObject(hdcMem, hOld);
    
        BITMAPINFOHEADER bmi = {0};
        bmi.biSize = sizeof(BITMAPINFOHEADER);
        bmi.biPlanes = 1;
        bmi.biBitCount = 32;
        bmi.biWidth = ScreenX;
        bmi.biHeight = -ScreenY;
        bmi.biCompression = BI_RGB;
        bmi.biSizeImage = 0;// 3 * ScreenX * ScreenY;
    
        if(ScreenData)
            free(ScreenData);
        ScreenData = (BYTE*)malloc(4 * ScreenX * ScreenY);
    
        GetDIBits(hdcMem, hBitmap, 0, ScreenY, ScreenData, (BITMAPINFO*)&bmi, DIB_RGB_COLORS);
    
        ReleaseDC(GetDesktopWindow(),hScreen);
        DeleteDC(hdcMem);
        DeleteObject(hBitmap);
    }
    
    inline int PosB(int x, int y) 
    {
        return ScreenData[4*((y*ScreenX)+x)];
    }
    
    inline int PosG(int x, int y) 
    {
        return ScreenData[4*((y*ScreenX)+x)+1];
    }
    
    inline int PosR(int x, int y) 
    {
        return ScreenData[4*((y*ScreenX)+x)+2];
    }
    
    bool ButtonPress(int Key)
    {
        bool button_pressed = false;
    
        while(GetAsyncKeyState(Key))
            button_pressed = true;
    
        return button_pressed;
    }
    
    int main() 
    {
        while (true) 
        {
           if (ButtonPress(VK_SPACE))
           {  
    
              // Print out current cursor position
              POINT p;
              GetCursorPos(&p);
              printf("X:%d Y:%d \n",p.x,p.y);
              // Print out RGB value at that position
              std::cout << "Bitmap: r: " << PosR(p.x, p.y) << " g: " << PosG(p.x, p.y) << " b: " << PosB(p.x, p.y) << "\n";
    
           } else if (ButtonPress(VK_ESCAPE))
           {
              printf("Quit\n");
              break;
           } else if (ButtonPress(VK_SHIFT))
           {
              ScreenCap();
              printf("Captured\n");
           }
        }
    
        system("PAUSE");
        return 0;
    }
    

提交回复
热议问题