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

如何将C# Bitmap转换为GDI+原生C++ Bitmap并保留Alpha通道?

问题描述

我在C#中通过以下代码创建带Alpha通道的Bitmap:

Image image = Image.FromFile("xxx.png");
Bitmap bitmap = new(image.Width, image.Height, PixelFormat.Format32bppArgb);
Graphics graphics = Graphics.FromImage(bitmap);
graphics.DrawImage(image, 0, 0, image.Width, image.Height);

现在需要将该Bitmap传入C++,我尝试了如下转换函数,但转换后Alpha通道丢失:

Gdiplus::Bitmap* Utils::BitmapConverter::Convert(Drawing::Bitmap^ managedBitmap)
{
    IntPtr hBitmap = managedBitmap->GetHbitmap();
    return Gdiplus::Bitmap::FromHBITMAP((HBITMAP)hBitmap.ToPointer(), NULL);
}

请问该如何修改这个转换函数?

解决方案

问题根源

managedBitmap->GetHbitmap()默认会忽略Alpha通道,它会把透明区域替换为黑色,生成的HBITMAP不包含Alpha信息,导致后续转换为Gdiplus::Bitmap时丢失透明度。

修改后的转换函数

改用GetHbitmap(Color::Transparent)来保留Alpha通道,同时必须手动释放GetHbitmap创建的HBITMAP(避免内存泄漏),修改后的代码如下:

#include <gdiplus.h>
#include <System.Drawing.h>

Gdiplus::Bitmap* Utils::BitmapConverter::Convert(Drawing::Bitmap^ managedBitmap)
{
    // 获取包含Alpha通道的HBITMAP
    IntPtr hBitmap = managedBitmap->GetHbitmap(System::Drawing::Color::Transparent);
    HBITMAP hbmp = static_cast<HBITMAP>(hBitmap.ToPointer());

    // 从HBITMAP创建Gdiplus Bitmap
    Gdiplus::Bitmap* gdiBitmap = Gdiplus::Bitmap::FromHBITMAP(hbmp, NULL);

    // 手动释放HBITMAP,避免内存泄漏
    DeleteObject(hbmp);

    return gdiBitmap;
}

额外注意事项

  • 确保C++项目已正确初始化GDI+:程序启动时调用GdiplusStartup,退出时调用GdiplusShutdown,否则Gdiplus::Bitmap的操作可能失败。
  • 如果原C# Bitmap的像素格式不是32bppArgb,建议先在C#端转换为该格式后再传入,避免格式不兼容问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 19:18:14