bcubeu26dncs
bcubeu26dncs

Reputation: 93

GetDIBits returns invalid colors array of compatible bitmap

I'm, trying to take an array of pixels from compatible bitmap(it completly filled by RGB(0,0,255) color) throught GetDIBits, but it return another colors. And, when I try to change an array it actually returns an exception. What is wrong?

case WM_PAINT:
{
    PAINTSTRUCT ps;
    HDC hdc = BeginPaint(hwnd, &ps);
    HBRUSH hb = CreateSolidBrush(RGB(0, 0, 255));

    HDC hdcc = CreateCompatibleDC(hdc);
    HBITMAP bm = CreateCompatibleBitmap(hdc, r.right, r.bottom);

    SelectObject(hdcc, bm);
    SelectObject(hdcc, hb);

    Rectangle(hdcc, 0, 0, r.right, r.bottom); //filling by the blue brush

    BITMAPINFO bi = { 0 };

    bi.bmiHeader.biSize = sizeof(bi.bmiHeader);

    int er = GetDIBits(hdcc, bm, 0, 0, NULL, &bi, DIB_RGB_COLORS);
    //In GetDIBits, as HDC argument must be compatible, yes?

    if (!er)
    {
        cout << "ERROR HERE:"<< GetLastError()<<"ENDS";
    }

    COLORREF *buf = new COLORREF(bi.bmiHeader.biSizeImage); //Yet, still, I have not understood, which type array should be - char, BYTE, COLORREF or anything else

    bi.bmiHeader.biBitCount = 32;
    bi.bmiHeader.biCompression = BI_RGB;
    bi.bmiHeader.biHeight = abs(bi.bmiHeader.biHeight);

    GetDIBits(hdcc, bm, 0, bi.bmiHeader.biHeight, buf, &bi, DIB_RGB_COLORS);

    for (int i(0); i < 100; i++)
    {
        cout << (int)GetRValue(buf[i]) << ",";
        cout << (int)GetGValue(buf[i]) << ",";
        cout << (int)GetBValue(buf[i]) << ",";
        cout << endl;
    }

    SetDIBits(hdcc, bm, 0, bi.bmiHeader.biHeight, buf, &bi, DIB_RGB_COLORS);

    delete []buf;

    BitBlt(hdc, 0, 0, r.right, r.bottom, hdcc, 0, 0, SRCCOPY);

    DeleteObject(hb);
    DeleteDC(hdcc);
    DeleteObject(bm);

    EndPaint(hwnd, &ps);
}
break;

enter image description here

Upvotes: 0

Views: 150

Answers (1)

Adrian McCarthy
Adrian McCarthy

Reputation: 47952

There are several problems with this line:

COLORREF *buf = new COLORREF(bi.bmiHeader.biSizeImage);
  1. As @PaulMcKenzie pointed out, you meant to use square brackets rather parentheses so that you allocate space for an array.
  2. biSizeImage is in bytes, not COLORREFs, so this over-allocates.
  3. biSizeImage may be zero, in which case you'll allocate nothing. When biSizeImage is zero, it means you have to compute the actual size necessary.
  4. At this point in the program, biSizeImage is the size of the device-dependent ("compatible") bitmap, which may very well be different than the size you need for the device-independent data you're trying to grab.

Upvotes: 1

Related Questions