C++ 如何读取屏幕像素?

C++ 如何读取屏幕像素?,c++,windows,screen-capture,C++,Windows,Screen Capture,我想读取一个矩形区域,或整个屏幕的像素。好像屏幕截图按钮被按下了 我是怎么做到的 编辑:工作代码: void CaptureScreen(char *filename) { int nScreenWidth = GetSystemMetrics(SM_CXSCREEN); int nScreenHeight = GetSystemMetrics(SM_CYSCREEN); HWND hDesktopWnd = GetDesktopWindow(); HDC hDe

我想读取一个矩形区域,或整个屏幕的像素。好像屏幕截图按钮被按下了

我是怎么做到的

编辑:工作代码:

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);
}
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);
选择对象(hCaptureDC、hCaptureBitmap);
BitBlt(hCaptureDC,0,0,nscreeenwidth,nscreeenheight,hDesktopDC,0,0,SRCCOPY | CAPTUREBLT);
BITMAPINFO bmi={0};
bmi.bmiHeader.biSize=sizeof(bmi.bmiHeader);
bmi.bmiHeader.biWidth=nsScreenWidth;
bmi.bmiHeader.biHeight=屏幕高度;
bmi.bmiHeader.biPlanes=1;
bmi.bmiHeader.biBitCount=32;
bmi.bmiHeader.biCompression=BI_RGB;
RGBQUAD*pPixels=新的RGBQUAD[nScreenWidth*nScreenHeight];
格蒂比特(
hCaptureDC,
hCaptureBitmap,
0,  
屏幕高度,
皮克斯,
&体重指数,
DIB_RGB_颜色
);  
//写:
INTP;
int x,y;
FILE*fp=fopen(文件名,“wb”);
对于(y=0;y
使用BitBlt()制作屏幕截图。快照的大小由nWidth和nHeight参数设置。左上角用nXSrc和nYSrc参数设置。

HBITMAP不是指针或数组,它是由Windows管理的句柄,仅对Windows有意义。您必须要求Windows将像素复制到某个地方以供使用

要获得单个像素值,甚至无需位图即可使用。如果需要访问多个像素,则速度会很慢


要将位图复制到您可以访问的内存中,请使用。

重新阅读您的问题,听起来我们可能与屏幕截图相切。如果您只想检查屏幕上的一些像素,可以使用


如果要读取大量像素,最好先进行屏幕截图,然后使用。调用
GetPixel
无数次会很慢。

从代码开始,忽略错误检查

// 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;

您可以使用以下代码读取屏幕像素:

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

如果答案对您有帮助,请不要忘记接受。我知道,我还没有找到有效的答案,或者您需要添加更多的信息,例如您尝试了什么,失败了什么。您使用了哪些包括/编译器等?@Paul如果我不得不猜测它将是在Visual Studio上编译的winuser.h和wingdi.h,但是我可能遗漏了一些东西。是的,我想读取一个矩形像素(或者如果更容易的话,一次读取整个屏幕)。我不知道如何使用GetDIBits函数,我无法理解参数的任何术语,我不知道它是如何工作的。我让你的函数工作,但我想使用更有效的方法读取超过1像素的数据。我无法使用此GetDIBits函数。我为hCaptureBitmap放置了什么?还有,我在那里放置了什么窗口HDC,我的桌面还是我的程序自己的窗口?为什么要删除最初的捕获代码?我发布的内容应该添加到您拥有的内容中,而不是替换它。这就是为什么我在
hCaptureBitmap
hCaptureDC
中使用了您的变量名。找到了代码,现在我更新了,仍然返回黑色图像
HWND desktop = GetDesktopWindow();
HDC desktopHdc = GetDC(desktop);
COLORREF color = GetPixel(desktopHdc, x, y);