You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

从字节数组生成Bitmap无显示:我的代码问题出在哪里?

字节数组生成Bitmap无法在图片控件显示的问题排查

我尝试从字节数组生成Bitmap并设置到图片控件PICTURE_MY上,但图片无法显示。以下是我的代码实现,请帮忙排查问题:

OnInitDialog 代码

PICTURE_MY.GetWindowRect(&rect); //PICTURE_MY 是我的图片控件
MAX_CANVAS_W = rect.right - rect.left;
MAX_CANVAS_H = rect.bottom - rect.top;
layerOne = new BYTE[3*((MAX_CANVAS_W-2)*(MAX_CANVAS_H-2))];
pitch = MAX_CANVAS_W - 2;

int count = 0;
while (count < 3 * ((MAX_CANVAS_W - 2) * (MAX_CANVAS_H - 2)))
{
    layerOne[count] = 255;
    count++;
}

OnPaint 代码

HBITMAP h_bitmap = CreateBitmap(pitch, MAX_CANVAS_H - 2, 1, 24, layerOne);
CImage image;
image.Attach(h_bitmap);

PICTURE_MY.SetBitmap(image);

另外,我用以下代码可以正常显示,但效率太低,不想采用:

CClientDC dc(this);
for (int y = 0; y < MAX_CANVAS_H - 2; y++) 
{
    for (int x = 0; x < pitch; x++) 
    {
        COLORREF color = RGB(layerOne[3*(y*pitch+x)], layerOne[3 * (y * pitch + x)+1], layerOne[3 * (y * pitch + x)+2]);
        dc.SetPixel(PICTURE_LEFTTOP.x+1 + x, PICTURE_LEFTTOP.y+y+1, color);
        
    }
}

问题原因及解决方法

  1. DIB对齐与格式兼容问题
    CreateBitmap生成的是依赖设备的位图(DDB),24位DDB要求每行像素数据按4字节对齐。如果你的pitch(即每行像素数)不是4的倍数,数据排布不符合要求,会导致位图解析失败。

解决方法:改用CreateDIBSection创建设备无关位图(DIB),它支持自定义行间距,无需强制4字节对齐,且兼容性更好:

// 替换OnPaint中的原代码
BITMAPINFO bmi = {0};
bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bmi.bmiHeader.biWidth = pitch;
bmi.bmiHeader.biHeight = -(MAX_CANVAS_H - 2); // 负数值表示像素数组按顶行在前的顺序存储
bmi.bmiHeader.biPlanes = 1;
bmi.bmiHeader.biBitCount = 24;
bmi.bmiHeader.biCompression = BI_RGB;
bmi.bmiHeader.biSizeImage = 3 * pitch * (MAX_CANVAS_H - 2);

HBITMAP h_bitmap = CreateDIBSection(NULL, &bmi, DIB_RGB_COLORS, NULL, NULL, 0);
if (h_bitmap)
{
    // 将layerOne的数据拷贝到位图内存中
    BITMAP bmp;
    GetObject(h_bitmap, sizeof(bmp), &bmp);
    BYTE* pBits = (BYTE*)bmp.bmBits;
    memcpy(pBits, layerOne, 3 * pitch * (MAX_CANVAS_H - 2));
    
    PICTURE_MY.SetBitmap(h_bitmap);
    DeleteObject(h_bitmap); // SetBitmap会接管位图句柄,此处可释放
}
  1. 像素顺序不匹配
    Windows 24位位图默认采用BGR(蓝、绿、红)的像素顺序,但你的低效代码中用RGB(红,绿,蓝)转换,说明layerOne数组是RGB顺序。如果直接用原数组生成位图,颜色会出现异常(全白场景可能看不出,但其他颜色会出错)。

如果要保留RGB顺序的数组,可修改BITMAPINFO的颜色掩码:

bmi.bmiHeader.biBitCount = 24;
bmi.bmiHeader.biCompression = BI_BITFIELDS;
// 定义RGB对应的掩码,匹配数组的颜色顺序
DWORD dwMask[] = {0x00FF0000, 0x0000FF00, 0x000000FF};
memcpy(&bmi.bmiColors, dwMask, sizeof(dwMask));
  1. CImage中转冗余
    原代码里通过CImage中转位图句柄完全没必要,SetBitmap直接接收HBITMAP即可,去掉中转能减少资源管理风险。

内容的提问来源于stack exchange,提问作者이지선

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 19:01:24