9

I would like to get the RGB values of a pixel at different x, y coordinates on the screen. How would I go about this in C++?

I'm trying to create my own gaussian blur effect.

This would be in Windows 7.

Edit

What libraries need to be included for this to run?

What I have going:

#include <iostream>

using namespace std ;

int main(){

    HDC dc = GetDC(NULL);
    COLORREF color = GetPixel(dc, 0, 0);
    ReleaseDC(NULL, dc);

    cout << color; 

}
Cody Gray - on strike
  • 239,200
  • 50
  • 490
  • 574
rectangletangle
  • 50,393
  • 94
  • 205
  • 275

2 Answers2

15

You can use GetDC on the NULL window to get a device context for the whole screen, and can follow that up with a call to GetPixel:

HDC dc = GetDC(NULL);
COLORREF color = GetPixel(dc, x, y);
ReleaseDC(NULL, dc);

Of course, you'd want to only acquire and release the device context once while doing all the pixel-reading for efficiency.

templatetypedef
  • 362,284
  • 104
  • 897
  • 1,065
  • @Anteater7171- If you `#include ` that should be sufficient, provided that you're building from Visual Studio. I used this trick many years back without doing anything special beyond this. – templatetypedef Jan 29 '11 at 22:54
  • @Anteater7171- Sorry, I know nothing about that compiler, and can't help you out much. You probably want to link in some of the system DLL files like `gdi32.lib`, and it might be worth looking up on MSDN what specific libraries are required. – templatetypedef Jan 29 '11 at 23:17
10

As mentioned in a previous post, you want the GetPixel function from the Win32 API.

GetPixel sits inside gdi32.dll, so if you have a proper environment setup, you should be able to include windows.h (which includes wingdi.h) and you should be golden.

If you have a minimal environment setup for whatever reason, you could also use LoadLibrary on gdi32.dll directly.

The first parameter to GetPixel is a handle to the device context, which can be retrieved by calling the GetDC function(which is also available via <windows.h>).

A basic example that loads GetPixel from the dll and prints out the color of the pixel at your current cursor position is as follows.

#include<windows.h>
#include<stdio.h>

typedef WINAPI COLORREF (*GETPIXEL)(HDC, int, int);

int main(int argc, char** argv)
{

    HINSTANCE _hGDI = LoadLibrary("gdi32.dll");
    if(_hGDI)
    {
        while(true) {
            GETPIXEL pGetPixel = (GETPIXEL)GetProcAddress(_hGDI, "GetPixel");
            HDC _hdc = GetDC(NULL);
            if(_hdc)
            {
                POINT _cursor;
                GetCursorPos(&_cursor);
                COLORREF _color = (*pGetPixel) (_hdc, _cursor.x, _cursor.y);
                int _red = GetRValue(_color);
                int _green = GetGValue(_color);
                int _blue = GetBValue(_color);

                printf("Red: 0x%02x\n", _red);
                printf("Green: 0x%02x\n", _green);
                printf("Blue: 0x%02x\n", _blue);
            }
            FreeLibrary(_hGDI);
        }
    }
    return 0;
}
Coal
  • 346
  • 3
  • 9
syllogism
  • 655
  • 1
  • 4
  • 12
  • 1
    Notice that if you want to do this for more than a few pixels `GetPixel` is dog slow. The fast way is to create a compatible DC, create and select a DIBSection in it and then access directly the memory that backs its pixels. – Matteo Italia Jul 10 '17 at 00:26
  • At a glance, it looks like 1) the positioning of the while loop (which did not exist in the original answer) could be improved further, and 2) calling the `ReleaseDC` is needed in this case, because it's "common DC" (`GetDC(NULL)` - see [this](https://stackoverflow.com/q/52508939/10027592)). 3) Why is this answer different than the other one? - It seems like the asker picked this answer because the normal way (like the other answer) doesn't work for him/her, and it looks like the asker deleted his/her comments in the other answer. – starriet Aug 31 '23 at 22:35