GetDIBits 返回兼容位图的无效颜色数组

Posted

技术标签:

【中文标题】GetDIBits 返回兼容位图的无效颜色数组【英文标题】:GetDIBits returns invalid colors array of compatible bitmap 【发布时间】:2018-08-09 19:36:08 【问题描述】:

我正在尝试从兼容位图(完全由RGB(0,0,255) 颜色填充)到GetDIBits 获取像素数组,但它返回另一种颜色。而且,当我尝试更改数组时,它实际上返回了一个异常。怎么了?

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

【问题讨论】:

sizeof(bi.bmiHeader); 的结果是什么?可能需要打包它。 "但它返回另一种颜色" -- 什么颜色? “返回异常” -- 什么异常?来吧,不要让我们通过猜测浪费时间。 @chux,它返回 40 @ArturKlochko 见bmp,我预计是14。可能需要发布BITMAPINFO 定义并提供minimal reproducible example 的其他详细信息 看看你对“新”的调用。看出什么不对了吗?比如可能使用括号而不是方括号? 【参考方案1】:

这行有几个问题:

COLORREF *buf = new COLORREF(bi.bmiHeader.biSizeImage);
    正如@PaulMcKenzie 指出的那样,您的意思是使用方括号而不是括号,以便为数组分配空间。 biSizeImage 以字节为单位,而不是 COLORREFs,所以这会过度分配。 biSizeImage 可能为零,在这种情况下,您不会分配任何内容。当biSizeImage 为零时,这意味着您必须计算所需的实际大小。 此时在程序中,biSizeImage 是设备相关(“兼容”)位图的大小,它很可能与您尝试的与设备无关的数据所需的大小不同抓住。

【讨论】:

以上是关于GetDIBits 返回兼容位图的无效颜色数组的主要内容,如果未能解决你的问题,请参考以下文章

WinAPI/GDI:如何使用 GetDIBits() 为位图合成颜色表?

GetDIBits 遍历位图 获取像素的颜色值(RGB)

GetDIBits 遍历位图 获取像素的颜色值(RGB)

使用 Winsock、GetDIBits 和 SetDiBits 进行位图传输 [关闭]

GetDIBits 返回所有值为 0 的数组

处理 GetDIBits() 返回的像素缓冲区的正确方法是啥?