4

First i load the image "cool.bmp".. load is fine. then i call the function "getPixArray" but it fails.

  case WM_CREATE:// runs once on creation of window
            hBitmap = (HBITMAP)LoadImage(NULL, L"cool.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE );
            if(hBitmap == NULL)
                ::printToDebugWindow("Error: loading bitmap\n");
            else 
                BYTE* b = ::getPixArray(hBitmap);     

my getPixArray function

  BYTE* getPixArray(HBITMAP hBitmap)
        {
        HDC hdc,hdcMem;

        hdc = GetDC(NULL);
        hdcMem = CreateCompatibleDC(hdc); 

        BITMAPINFO MyBMInfo = {0};
        // Get the BITMAPINFO structure from the bitmap
        if(0 == GetDIBits(hdcMem, hBitmap, 0, 0, NULL, &MyBMInfo, DIB_RGB_COLORS))
        {
            ::printToDebugWindow("FAIL\n");
        }

        // create the bitmap buffer
        BYTE* lpPixels = new BYTE[MyBMInfo.bmiHeader.biSizeImage];

        MyBMInfo.bmiHeader.biSize = sizeof(MyBMInfo.bmiHeader);
        MyBMInfo.bmiHeader.biBitCount = 32;  
        MyBMInfo.bmiHeader.biCompression = BI_RGB;  
        MyBMInfo.bmiHeader.biHeight = (MyBMInfo.bmiHeader.biHeight < 0) ? (-MyBMInfo.bmiHeader.biHeight) : (MyBMInfo.bmiHeader.biHeight); 

        // get the actual bitmap buffer
        if(0 == GetDIBits(hdc, hBitmap, 0, MyBMInfo.bmiHeader.biHeight, (LPVOID)lpPixels, &MyBMInfo, DIB_RGB_COLORS))
        {
            ::printToDebugWindow("FAIL\n");
        }

        return lpPixels;
    }

This function is supposed to get a reference to the internal pixel array used to draw the image. but both 'FAIL' messages print to the console. Can anyone identify the error or better produce a working version of this function so i can learn from it? ive been stuck for days on this, please help!

This is the were i got most of this code from: GetDIBits and loop through pixels using X, Y

This is the image i used: "cool.bmp" is a 24-bit Bitmap. Width:204 Height: 204 enter image description here

Community
  • 1
  • 1
Anthony Raimondo
  • 1,621
  • 2
  • 24
  • 40

1 Answers1

8

Your first function call fails because you did not initialise MyBMInfo.bmiHeader.biSize. You need to do this:

...
BITMAPINFO MyBMInfo = {0};
MyBMInfo.bmiHeader.biSize = sizeof(MyBMInfo.bmiHeader);
// Get the BITMAPINFO structure from the bitmap
if(0 == GetDIBits(hdcMem, hBitmap, 0, 0, NULL, &MyBMInfo, DIB_RGB_COLORS))
....

Once you fix that, the rest of the code will work as intended.

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
  • 2
    Aren't "output parameters" that need to be prefilled wonderful? Of course there's a good reason -- the `bmiHeader.biSize` field acts as a schema identifier and provides powerful capabilities for future Windows versions to return more information to apps that are aware of the expanded structure... but the fact that the documentation doesn't say exactly what fields need to be preset is annoying to say the least. – Ben Voigt Jun 15 '13 at 22:48