Thread: Getting Pixel Colour Screen

  1. #1
    Registered User
    Join Date
    Mar 2006
    Posts
    10

    Getting Pixel Colour Screen

    Hi, I’m trying to get the colour of a pixel on the screen. I have tried using getpixel(), however when getting the colour of the whole screen, pixel by pixel, it takes a long time for what I want it for.
    For this reason I tried to find an alternative, and found information about using GetDIBits(). I understand the general idea behind using it I think, but can’t get it to work, since the limited programming I know is more mathematical and to do with modelling physics.
    I’m programming in the windows console, if someone could link me to a good tutorial, or even better provide the code required to get a pixel colour on the screen using this method I would be much appreciated.

  2. #2
    Slave MadCow257's Avatar
    Join Date
    Jan 2005
    Posts
    735
    Probably not what you want, but there are other ways to optimize that might be more effective.

    How are you looping through the pixels?
    Are you in 24 bit mode?
    Is using the console neccesary?
    Are you processing all the pixels or can some be ignored?

  3. #3
    Yes, my avatar is stolen anonytmouse's Avatar
    Join Date
    Dec 2002
    Posts
    2,544
    Welcome to the forums!

    The best way to do this is to copy the screen into a dib section. Quick sample code showing this is provided below:
    Code:
    #include <windows.h>
    #include <stdio.h>
    
    struct tagScreen
    {
        DWORD*     pixels;  /* Pointer to raw bitmap bits. Access with: pixels[(y * Screen.cx) + x] */
        size_t     cx, cy;  /* Width and height of bitmap. */
        HBITMAP    hBmp;
        HDC        hdcMem;
        HDC        hdcScreen;
    } Screen;
    
    /* Call once to setup.
     */
    void xSetupScreenBitmap(void)
    {
        BITMAPINFO bmp   = { 0 };
    
        Screen.cx = GetSystemMetrics(SM_CXSCREEN);
        Screen.cy = GetSystemMetrics(SM_CYSCREEN);
    
        bmp.bmiHeader.biSize        = sizeof(BITMAPINFOHEADER);
        bmp.bmiHeader.biWidth       = Screen.cx;
        bmp.bmiHeader.biHeight      = -(int) Screen.cy;
        bmp.bmiHeader.biPlanes      = 1;
        bmp.bmiHeader.biBitCount    = 32;
        bmp.bmiHeader.biCompression = BI_RGB;
    
        Screen.hBmp = CreateDIBSection(NULL, &bmp, DIB_RGB_COLORS, (void**) &Screen.pixels, NULL, 0);
        Screen.hdcMem = CreateCompatibleDC(NULL);
        SelectObject(Screen.hdcMem, Screen.hBmp);
    
        Screen.hdcScreen = CreateDC(TEXT("DISPLAY"), NULL, NULL, NULL);
    }
    
    /* Call to copy the current screen into the screen bitmap.
     */
    void xCopyScreen(void)
    {
        BitBlt(Screen.hdcMem, 0, 0, Screen.cx, Screen.cy, Screen.hdcScreen, 0, 0, SRCCOPY);
    }
    
    /* Convert a RGB value to the BGR used by Windows COLORREF values.
     */
    COLORREF RGB2BGR(DWORD color)
    {
        return RGB(GetBValue(color), GetGValue(color), GetRValue(color));
    }
    
    
    int main(void)
    {
        size_t x, y;
    
        xSetupScreenBitmap(); /* Call once for setup. */
        xCopyScreen();        /* Call whenever you want a fresh copy of the screen. */
    
        /* Shows how to loop through all pixels. */
        for (x = 0; x < Screen.cx; x++)
        {
            for (y = 0; y < Screen.cy; y++)
            {
                /* Use Screen.pixels[(y * Screen.cx) + x] as required. */
    
                /* TEST CODE: Output slighlty altered pixels to the screen. */
                SetPixel(Screen.hdcScreen, x, y, RGB2BGR(Screen.pixels[(y * Screen.cx) + x]) + 10);
            }
        }
    
        return 0;
    }
    Last edited by anonytmouse; 03-14-2006 at 07:59 PM. Reason: Made correction for C++ as pointed out below. Thanks.

  4. #4
    Registered User
    Join Date
    Mar 2006
    Posts
    10
    Anonytmouse thank you very much for the reply, it was exactly what I was looking for.
    I did get an error when I tried to run it, I had to replace the line:
    Code:
    Screen.hBmp = CreateDIBSection(NULL, &bmp, DIB_RGB_COLORS, &Screen.pixels, NULL, 0);
    With:
    Code:
    Screen.hBmp = CreateDIBSection(NULL, &bmp, DIB_RGB_COLORS, (void **)&Screen.pixels, NULL, 0);
    But other than that it worked great.

    For anyone interested in the speed difference between this method, and using getpixel(), I found the time to use each method to get all the pixels of the screen. Using getpixel() it took 5.594 seconds, compared with the method provided by Anonytmouse which took 0.32 seconds, which is about 1/17.5 of the time.

    MadCow257 thank you for the reply as well, I am going to try any optimize it to make it more efficient, however I have to get all the pixels of the screen for what I am trying to do, and for this reason other than getting each row one at a time I cant see a better way. Also you mention me using the console as if it might have an effect on the speed of the code, might this be the case? I only use the console to allow for easy printing of values during making a program, to the screen.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Reading pixel color data from screen
    By JJFMJR in forum Windows Programming
    Replies: 8
    Last Post: 08-22-2008, 12:27 PM
  2. Feedback: Functional Specification Wording
    By Ragsdale85 in forum C++ Programming
    Replies: 0
    Last Post: 01-18-2006, 04:56 PM
  3. char copy
    By variable in forum C Programming
    Replies: 8
    Last Post: 02-06-2005, 10:18 PM
  4. i am not able to figure ot the starting point of this
    By youngashish in forum C++ Programming
    Replies: 7
    Last Post: 10-07-2004, 02:41 AM
  5. Green Pixel On My Screen???
    By (TNT) in forum A Brief History of Cprogramming.com
    Replies: 18
    Last Post: 01-21-2002, 08:09 AM