How to read the screen pixels?

后端 未结 5 1662
被撕碎了的回忆
被撕碎了的回忆 2020-12-01 08:17

I want to read a rectangular area, or whole screen pixels. As if screenshot button was pressed.

How i do this?

Edit: Working code:



        
相关标签:
5条回答
  • 2020-12-01 08:58

    You make a screenshot with BitBlt(). The size of the shot is set with the nWidth and nHeight arguments. The upper left corner is set with the nXSrc and nYSrc arguments.

    0 讨论(0)
  • 2020-12-01 09:11

    Starting with your code and omitting error checking ...

    // Create a BITMAPINFO specifying the format you want the pixels in.
    // To keep this simple, we'll use 32-bits per pixel (the high byte isn't
    // used).
    BITMAPINFO bmi = {0};
    bmi.bmiHeader.biSize = sizeof(bmi.bmiHeader);
    bmi.bmiHeader.biWidth = nScreenWidth;
    bmi.bmiHeader.biHeight = nScreenHeight;
    bmi.bmiHeader.biPlanes = 1;
    bmi.bmiHeader.biBitCount = 32;
    bmi.bmiHeader.biCompression = BI_RGB;
    
    // Allocate a buffer to receive the pixel data.
    RGBQUAD *pPixels = new RGBQUAD[nScreenWidth * nScreenHeight];
    
    // Call GetDIBits to copy the bits from the device dependent bitmap
    // into the buffer allocated above, using the pixel format you
    // chose in the BITMAPINFO.
    ::GetDIBits(hCaptureDC,
                hCaptureBitmap,
                0,  // starting scanline
                nScreenHeight,  // scanlines to copy
                pPixels,  // buffer for your copy of the pixels
                &bmi,  // format you want the data in
                DIB_RGB_COLORS);  // actual pixels, not palette references
    
    // You can now access the raw pixel data in pPixels.  Note that they are
    // stored from the bottom scanline to the top, so pPixels[0] is the lower
    // left pixel, pPixels[1] is the next pixel to the right,
    // pPixels[nScreenWidth] is the first pixel on the second row from the
    // bottom, etc.
    
    // Don't forget to free the pixel buffer.
    delete [] pPixels;
    
    0 讨论(0)
  • 2020-12-01 09:12

    Rereading your question, it sounds like we may have gotten off on a tangent with the screen capture. If you just want to check some pixels on the screen, you can use GetPixel.

    HDC hdcScreen = ::GetDC(NULL);
    COLORREF pixel = ::GetPixel(hdcScreen, x, y);
    ReleaseDC(NULL, hdcScreen);
    if (pixel != CLR_INVALID) {
      int red = GetRValue(pixel);
      int green = GetGValue(pixel);
      int blue = GetBValue(pixel);
      ...
    } else {
      // Error, x and y were outside the clipping region.
    }
    

    If you're going to read a lot of pixels, then you're better off with a screen capture and then using GetDIBits. Calling GetPixel zillions of times will be slow.

    0 讨论(0)
  • 2020-12-01 09:13

    You can use the code below to read the screen pixels:

    HWND desktop = GetDesktopWindow();
    HDC desktopHdc = GetDC(desktop);
    COLORREF color = GetPixel(desktopHdc, x, y);
    
    0 讨论(0)
  • 2020-12-01 09:18

    HBITMAP is not a pointer or an array, it is a handle that is managed by Windows and has meaning only to Windows. You must ask Windows to copy the pixels somewhere for use.

    To get an individual pixel value, you can use GetPixel without even needing a bitmap. This will be slow if you need to access many pixels.

    To copy a bitmap to memory you can access, use the GetDIBits function.

    0 讨论(0)
提交回复
热议问题