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

如何将HBITMAP从GDI+ Bitmap中分离,避免原对象销毁后失效?

解决GDI+ Bitmap转HBITMAP后对象失效的问题

问题根源在于:GetHBITMAP返回的HBITMAP与原GDI+ Bitmap共享底层像素数据,当原Bitmap对象超出作用域被析构时,其占用的内存会被释放,导致关联的HBITMAP失效。要实现HBITMAP与原Bitmap完全分离,需要创建一个独立的HBITMAP并复制像素数据,彻底解绑依赖关系。

实现思路

  • 获取原GDI+ Bitmap的像素数据与格式信息
  • 创建独立的DIBSection类型HBITMAP(该类型拥有独立内存空间,不依赖原对象)
  • 将原Bitmap的像素数据完整复制到新HBITMAP的缓冲区
  • 确保原Bitmap销毁后,新HBITMAP可正常使用

完整代码示例

#include <GdiPlus.h>
#include <cstring>

#pragma comment(lib, "Gdiplus.lib")

HBITMAP GDIBITMAPToIndependentHBitmap()
{
    int width = 500;
    int height = 500;

    // 创建原GDI+ Bitmap并执行绘图操作
    Gdiplus::Bitmap myBitmap(width, height, Gdiplus::PixelFormat32bppRGB);
    Gdiplus::Graphics g(&myBitmap);
    Gdiplus::Pen blackpen(Gdiplus::Color(255, 0, 0, 0), 3);
    g.DrawRectangle(&blackpen, 10, 10, width - 20, height - 20);

    // 锁定原Bitmap获取像素数据
    Gdiplus::BitmapData bitmapData;
    Gdiplus::Rect rect(0, 0, width, height);
    if (myBitmap.LockBits(&rect, Gdiplus::ImageLockModeRead, Gdiplus::PixelFormat32bppRGB, &bitmapData) != Gdiplus::Status::Ok)
    {
        return nullptr;
    }

    // 构造BITMAPINFO用于创建独立HBITMAP
    BITMAPINFO bmpInfo = {0};
    bmpInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
    bmpInfo.bmiHeader.biWidth = width;
    bmpInfo.bmiHeader.biHeight = -height; // 负高度表示原点在图像顶部,与GDI+一致
    bmpInfo.bmiHeader.biPlanes = 1;
    bmpInfo.bmiHeader.biBitCount = 32;
    bmpInfo.bmiHeader.biCompression = BI_RGB;
    bmpInfo.bmiHeader.biSizeImage = width * height * 4;

    void* pNewBits = nullptr;
    HBITMAP hIndependentBitmap = CreateDIBSection(nullptr, &bmpInfo, DIB_RGB_COLORS, &pNewBits, nullptr, 0);
    if (!hIndependentBitmap || !pNewBits)
    {
        myBitmap.UnlockBits(&bitmapData);
        return nullptr;
    }

    // 复制像素数据到新HBITMAP
    memcpy(pNewBits, bitmapData.Scan0, bmpInfo.bmiHeader.biSizeImage);

    // 解锁原Bitmap
    myBitmap.UnlockBits(&bitmapData);

    return hIndependentBitmap;
}

关键注意事项

  • 使用LockBits/UnlockBits是安全访问GDI+ Bitmap像素数据的标准方式,避免直接内存访问的风险
  • CreateDIBSection创建的HBITMAP拥有独立内存,完全脱离原GDI+ Bitmap的依赖
  • 使用完独立HBITMAP后,必须调用DeleteObject(hIndependentBitmap)释放内存,避免泄漏

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 02:58:47