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

在HBITMAP上写入文本时遭遇HBITMAP与HDC不兼容问题求助

问题分析与修复方案

核心错误点

  • DDB与DC格式不兼容:CreateBitmap生成的是设备相关位图(DDB),必须与目标DC的像素格式完全匹配才能被SelectObject成功选入。你创建的是8位位图,但CreateCompatibleDC(hdc)生成的DC与屏幕DC格式一致(现代系统多为24/32位真彩色),格式不匹配导致选入失败,后续所有操作都无法作用到位图上。
  • GetDIBits调用逻辑错误:第一次调用时位图未被选入DC,且BITMAPINFO初始化不完整,无法正确获取位图信息;后续调用时因位图未成功选入DC,自然返回0行。

修复后的代码

改用CreateDIBSection创建指定格式的设备无关位图(DIB),它可兼容任意DC,同时支持直接访问像素缓冲区,完美解决彩色位图需求:

// 初始化8位位图的BITMAPINFO(包含调色板)
BITMAPINFO MyBMInfo = {0};
MyBMInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
MyBMInfo.bmiHeader.biWidth = 10;
MyBMInfo.bmiHeader.biHeight = 10;
MyBMInfo.bmiHeader.biPlanes = 1;
MyBMInfo.bmiHeader.biBitCount = 8; // 指定8位彩色格式
MyBMInfo.bmiHeader.biCompression = BI_RGB;
// 计算行对齐后的缓冲区大小(GDI要求每行字节数为4的倍数)
MyBMInfo.bmiHeader.biSizeImage = ((10 * 8 + 31) / 32) * 4 * 10;

// 生成8位灰度调色板(可根据需求自定义RGB值)
for (int i = 0; i < 256; i++) {
    MyBMInfo.bmiColors[i].rgbRed = (BYTE)i;
    MyBMInfo.bmiColors[i].rgbGreen = (BYTE)i;
    MyBMInfo.bmiColors[i].rgbBlue = (BYTE)i;
    MyBMInfo.bmiColors[i].rgbReserved = 0;
}

BYTE* bmp_buffer = nullptr;
HDC hdc = GetDC(nullptr);
HDC memdc = CreateCompatibleDC(hdc);

// 创建DIBSection,直接获取像素缓冲区指针
HBITMAP hbitmap = CreateDIBSection(hdc, &MyBMInfo, DIB_RGB_COLORS, (void**)&bmp_buffer, nullptr, 0);
if (!hbitmap) {
    DeleteDC(memdc);
    ReleaseDC(nullptr, hdc);
    return;
}

// 将DIB选入DC(DIB可兼容任意DC,不会出现格式不匹配问题)
HBITMAP oldbmp = (HBITMAP)SelectObject(memdc, hbitmap);
if (!oldbmp) {
    DeleteObject(hbitmap);
    DeleteDC(memdc);
    ReleaseDC(nullptr, hdc);
    return;
}

// 设置文本颜色(匹配调色板中的白色索引)
SetTextColor(memdc, RGB(255, 255, 255));
SetBkMode(memdc, TRANSPARENT); // 可选:设置文本背景透明
TextOut(memdc, 0, 0, "123", 3);

// 恢复DC原有位图
SelectObject(memdc, oldbmp);

// 此时bmp_buffer已直接包含绘制后的像素数据,无需额外调用GetDIBits
// 若需验证,可执行以下代码:
// int lines = GetDIBits(memdc, hbitmap, 0, 10, bmp_buffer, &MyBMInfo, DIB_RGB_COLORS);

// 清理资源
DeleteObject(hbitmap);
DeleteDC(memdc);
ReleaseDC(nullptr, hdc);

关键说明

  • CreateDIBSection的优势:它创建的位图兼具DIB的格式灵活性和DDB的DC兼容性,同时允许直接操作像素缓冲区,省去了GetDIBits/SetDIBits的拷贝开销。
  • 8位位图的调色板要求:8位位图必须配套调色板,GDI才能正确解析颜色值。示例中使用灰度调色板,你可根据需求替换为自定义RGB调色板。
  • 文本颜色匹配:对于8位位图,SetTextColor传入的RGB值需与调色板中的某一项匹配,GDI会自动映射到对应的颜色索引;若无匹配项,会选择最接近的颜色。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 18:05:56