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

CreateCompatibleDC/SetPixel/BitBlt显示图像失败问题咨询

图像渲染失败的核心原因

你的代码存在6处GDI调用逻辑错误,直接导致绘制结果无法正常显示:

  • 新建位图未绑定到内存DC:调用CreateCompatibleDC创建的内存DC,默认仅选中一张1*1像素的单色占位位图,你创建的image位图没有通过SelectObject(Layout, image)选入内存DC,所有SetPixel绘制操作都落在那张默认单色位图上,和你创建的目标位图完全无关。
  • 兼容位图色彩格式不匹配:你创建image时传入的参考DC是Layout,此时Layout还绑定着默认单色位图,CreateCompatibleBitmap会参考传入DC的格式生成单色位图,根本无法存储rgbBlue/rgbGreen彩色像素,正确参考对象应该是最终绘制的目标DCdc。
  • SetPixel坐标传反:GDI接口的坐标参数顺序为(HDC, x坐标, y坐标, 颜色值),你的循环里j对应垂直方向行号(y值)、k对应水平方向列号(x值),但调用时传成了SetPixel(Layout, j, k, 颜色),x/y完全错位,大量像素会被画到位图边界外。
  • BitBlt源DC句柄错误:你创建的内存DC变量名为Layout,但BitBlt调用时传入的源DC是未定义的BCLayout,无效句柄会直接导致位块传输失败。
  • 拷贝尺寸和实际位图不匹配:BitBlt的拷贝宽高你硬编码为1000*1000,和实际创建的位图尺寸symbol->bitmap_width、symbol->bitmap_height不一致,要么拷贝到内存DC的无效空白区域,要么截断图像。
  • 缺少GDI资源回收逻辑:创建的内存DC、位图使用完成后没有调用DeleteDC、DeleteObject释放,会造成GDI资源泄漏,虽然不是本次显示失败的直接原因,但长期运行会导致绘图接口集体失效。
修正后的参考代码
// 以目标dc为参考创建兼容内存DC和位图
HDC Layout = CreateCompatibleDC(dc);
HBITMAP image = CreateCompatibleBitmap(dc, symbol->bitmap_width, symbol->bitmap_height);
// 把位图选入内存DC,保存默认占位位图方便后续还原
HBITMAP oldBmp = (HBITMAP)SelectObject(Layout, image);

int bit = 0;
for (int j = 0; j < symbol->bitmap_height; j++) { // j是y轴坐标
    for (int k = 0; k < symbol->bitmap_width; k++) { // k是x轴坐标
        if (symbol->bitmap[bit] == '1')
            SetPixel(Layout, k, j, rgbBlue); // 注意参数顺序:x在前,y在后
        else
            SetPixel(Layout, k, j, rgbGreen);
        bit++;
    }
}

// BitBlt参数修正:源DC用Layout,宽高和实际位图一致
BOOL success = BitBlt(
    dc, 
    1000, 1000, 
    symbol->bitmap_width, symbol->bitmap_height, 
    Layout, 
    0, 0, 
    SRCCOPY
);

// 资源还原与释放
SelectObject(Layout, oldBmp);
DeleteObject(image);
DeleteDC(Layout);

注意:如果BitBlt还是返回失败,可以直接调用GetLastError()拿到错误码定位具体问题,比如目标DC无效、坐标超出目标区域裁剪范围等。

内容的提问来源于stack exchange,提问作者WashedJavaProgrammer

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 17:45:41