How to read the screen pixels?

本小妞迷上赌 提交于 2020-01-09 04:43:29

问题


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

How i do this?

Edit: Working code:

void CaptureScreen(char *filename)
{
    int nScreenWidth = GetSystemMetrics(SM_CXSCREEN);
    int nScreenHeight = GetSystemMetrics(SM_CYSCREEN);
    HWND hDesktopWnd = GetDesktopWindow();
    HDC hDesktopDC = GetDC(hDesktopWnd);
    HDC hCaptureDC = CreateCompatibleDC(hDesktopDC);
    HBITMAP hCaptureBitmap = CreateCompatibleBitmap(hDesktopDC, nScreenWidth, nScreenHeight);
    SelectObject(hCaptureDC, hCaptureBitmap); 

    BitBlt(hCaptureDC, 0, 0, nScreenWidth, nScreenHeight, hDesktopDC, 0,0, SRCCOPY|CAPTUREBLT); 

    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; 

    RGBQUAD *pPixels = new RGBQUAD[nScreenWidth * nScreenHeight]; 

    GetDIBits(
        hCaptureDC, 
        hCaptureBitmap, 
        0,  
        nScreenHeight,  
        pPixels, 
        &bmi,  
        DIB_RGB_COLORS
    );  

    // write:
    int p;
    int x, y;
    FILE *fp = fopen(filename, "wb");
    for(y = 0; y < nScreenHeight; y++){
        for(x = 0; x < nScreenWidth; x++){
            p = (nScreenHeight-y-1)*nScreenWidth+x; // upside down
            unsigned char r = pPixels[p].rgbRed;
            unsigned char g = pPixels[p].rgbGreen;
            unsigned char b = pPixels[p].rgbBlue;
            fwrite(fp, &r, 1);
            fwrite(fp, &g, 1);
            fwrite(fp, &b, 1);
        }
    }
    fclose(fp);

    delete [] pPixels; 

    ReleaseDC(hDesktopWnd, hDesktopDC);
    DeleteDC(hCaptureDC);
    DeleteObject(hCaptureBitmap);
}

回答1:


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;



回答2:


Start here Various methods for capturing the screen




回答3:


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.




回答4:


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.




回答5:


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

HWND desktop = GetDesktopWindow();
HDC desktopHdc = GetDC(desktop);
COLORREF color = GetPixel(desktopHdc, x, y);



回答6:


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.



来源:https://stackoverflow.com/questions/2659932/how-to-read-the-screen-pixels

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!