I'm trying to access the pixel colors from a image file but can't seem to get it to work properly, my program is only accessing the pixel colors from my active window. I've been stuck on this for a few days and would really appreciate any help. I'm guessing i haven't set a proper handle to a device context to the image but i don't know how to do this

    HWND hDesktopWnd; HDC hDesktopDC; HDC hCaptureDC; 
    HBITMAP hCaptureBitmap; 
    BITMAPINFO bmi = {0};
    RGBQUAD *pPixels;
    LPTSTR szFileName; 
    BITMAP  bm;  int nScreenWidth, nScreenHeight; 
    szFileName = "test.bmp";


                nScreenWidth =  GetSystemMetrics(SM_CXSCREEN);
                nScreenHeight = GetSystemMetrics(SM_CYSCREEN);
                hDesktopWnd = GetDesktopWindow();
                hDesktopDC = GetDC(hwnd);
                hCaptureDC = CreateCompatibleDC(hDesktopDC);
                hCaptureBitmap = (HBITMAP)LoadImage( NULL, szFileName, IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION | LR_DEFAULTSIZE | LR_LOADFROMFILE );
                SelectObject(hCaptureDC, hCaptureBitmap); 
                BitBlt(hCaptureDC, 0, 0, nScreenWidth, nScreenHeight, hDesktopDC, 0,0, SRCCOPY|CAPTUREBLT); 

                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;

                pPixels = new RGBQUAD[nScreenWidth * nScreenHeight];

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


                for(int i= 0;i< nScreenHeight; i++){
                for(int j= 0;j< nScreenWidth; j++){
                    col.red_palette[i][j]   = pPixels[(nScreenWidth * (nScreenHeight-(i+1))) + j].rgbRed;   
                    col.green_palette[i][j] = pPixels[(nScreenWidth * (nScreenHeight-(i+1))) + j].rgbGreen; 
                    col.blue_palette[i][j]  = pPixels[(nScreenWidth * (nScreenHeight-(i+1))) + j].rgbBlue;  
                }
                }


                delete [] pPixels;
                ReleaseDC(hDesktopWnd, hDesktopDC);
                DeleteDC(hCaptureDC);
                DeleteObject(hCaptureBitmap);

Edited 4 Years Ago by blitzkrieg64

You haven't provided enough for me to guess what your trying to do..
You also cannot just implicitly convert a HWND to an HDC. It doesn't work like that. Putting the code in order, you can see that you had some HWND's being used as if it was a DC. I tried to fix as much as I can below and GUESS at what you were trying to do. I do not know what "Col" is. It seems to be some sort of 2D array of a struct of integers/unsigned chars but I do not want to guess.

void Meh(HWND hwnd, LPCTSTR szFileName)
{
    Bitmap BM;
    RGBQUAD *pPixels;
    BITMAPINFO bmi = {0};

    HDC hDesktopDC = GetDC(hwnd);
   // HWND hDesktopWnd = GetDesktopWindow();  No need.. Use NULL.
    HDC hCaptureDC = CreateCompatibleDC(NULL);
    int nScreenWidth =  GetSystemMetrics(SM_CXSCREEN);
    int nScreenHeight = GetSystemMetrics(SM_CYSCREEN);

    HBITMAP hCaptureBitmap = (HBITMAP)LoadImage(NULL, szFileName, IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION | LR_DEFAULTSIZE | LR_LOADFROMFILE);
    SelectObject(hCaptureDC, hCaptureBitmap);
    GetObject(hCaptureBitmap, sizeof(BM), &BM);  //I added this.

    BitBlt(hCaptureDC, 0, 0, nScreenWidth, nScreenHeight, hDesktopDC, 0,0, SRCCOPY | CAPTUREBLT);  //Copying the Bitmap File to the DC?

    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;

    pPixels = new RGBQUAD[nScreenWidth * nScreenHeight];

    GetDIBits(hCaptureDC, hCaptureBitmap, 0, nScreenHeight, pPixels, &bmi, DIB_RGB_COLORS);  //Copy the hBitmap to pPixels?

    //I stopped here because I didn't know what the rest is supposed to be. Are you trying to swap rows and flip the bitmap? Are you trying to edit the file with the pixels from the capture? Are you trying to load the file into a DC? Or are you trying to capture the screen and load one from a file at the same time?




    for(int i= 0; i < nScreenHeight; i++)
    {
        for(int j= 0; j < nScreenWidth; j++)
        {
            col.red_palette[i][j]   = pPixels[(nScreenWidth * (nScreenHeight-(i+1))) + j].rgbRed;
            col.green_palette[i][j] = pPixels[(nScreenWidth * (nScreenHeight-(i+1))) + j].rgbGreen;
            col.blue_palette[i][j]  = pPixels[(nScreenWidth * (nScreenHeight-(i+1))) + j].rgbBlue;
        }
    }


    delete [] pPixels;
    ReleaseDC(hDesktopWnd, hDesktopDC);
    DeleteDC(hCaptureDC);
    DeleteObject(hCaptureBitmap);
}

Perhaps this may help: http://tipsandtricks.runicsoft.com/Cpp/BitmapTutorial.html

It will teach you how to load a Bitmap onto a DC using Dibs.

Edited 4 Years Ago by triumphost

If you just want to access pixel values, there are simpler ways. I like the CImg library.

 #include "CImg.h"
    #include <iostream>
    using namespace cimg_library;

    int main()
    {
      CImg<float> image("image.bmp");
      CImgDisplay main_disp(image); // Display it, just for fun
      float pixvalR = image(10,10,0,0); // read red val at coord 10,10
      float pixvalG = image(10,10,0,1); // read green val at coord 10,10
      float pixvalB = image(10,10,0,2); // read blue val at coord 10,10
      std::cout << "R = " << pixvalR << ", G = " << pixvalG << ", B = " << pixvalB;

      std::cin.ignore();
    }

Edited 4 Years Ago by Moschops: really hate these new forum settings. They're so counter-intuitive and clumsy and kludgy, and they dump junk all over the screen as I'm trying to type :(

This article has been dead for over six months. Start a new discussion instead.