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

如何使用GDI+将带透明通道的位图保存为PNG格式文件

问题根因

你调用Bitmap::FromHBITMAP()方法加载带alpha通道的HBITMAP时,该接口默认会丢弃alpha通道信息,导致透明区域被填充为黑色,哪怕原始位图的alpha数据是正常的也不会被识别。

最简解决方案

无需通过HBITMAP中转,直接用提取到的HICON构造GDI+ Bitmap对象,会自动保留alpha通道信息,省去调色板创建的冗余步骤。

修正后可运行代码

using namespace Gdiplus;

SHFILEINFO sfi;
IImageList* piml;
HICON hicon;

// 从目标EXE路径获取最大尺寸图标
SHGetFileInfo(FILEPATH, 0, &sfi, sizeof(sfi), SHGFI_SYSICONINDEX);
SHGetImageList(SHIL_JUMBO, IID_IImageList, (void**)&piml);
piml->GetIcon(sfi.iIcon, 0x00000001, &hicon);

// 初始化GDI+
GdiplusStartupInput gdiplusStartupInput;
ULONG_PTR gdiplusToken;
GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);

// 直接用HICON构造Bitmap,自动保留alpha通道
Bitmap* h = new Bitmap(hicon);

// 获取PNG编码器CLSID(避免硬编码下标,兼容不同系统版本)
CLSID encoderClsid;
UINT num, sz;
GetImageEncodersSize(&num, &sz);
ImageCodecInfo* inf = new ImageCodecInfo[sz];
GetImageEncoders(num, sz, inf);
for (UINT i = 0; i < num; i++) {
    if (wcscmp(inf[i].MimeType, L"image/png") == 0) {
        encoderClsid = inf[i].Clsid;
        break;
    }
}

h->Save(L"PATH_TO_SAVE.png", &encoderClsid, NULL);

// 资源释放,避免内存泄漏
delete h;
delete[] inf;
DestroyIcon(hicon);
GdiplusShutdown(gdiplusToken);

其他注意事项

  • 原始代码中硬编码inf[4]作为PNG编码器的写法兼容性差,不同Windows版本的编码器排序可能不同,通过MIME类型匹配更稳定。
  • 用完的HICON、动态申请的编码器数组都需要主动释放,避免GDI资源泄漏。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 05:06:05