首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >有没有办法用透明GDI+从位图中保存PNG?

有没有办法用透明GDI+从位图中保存PNG?
EN

Stack Overflow用户
提问于 2021-09-27 09:34:54
回答 1查看 125关注 0票数 0

我正在尝试获取和图标从和exe,并保存为png与透明度。我已经能够用gdi+从其中获取位图,并将.bmp保存为正确的alpha通道(在Photoshop中选中)。但现在的问题是,当我想要将它保存为.png时,透明度不会传输到文件中(透明区域是黑色的)以下是我的代码:

代码语言:javascript
运行
复制
using namespace Gdiplus;

SHFILEINFO sfi;
IImageList* piml;
HICON hicon;

// Getting the largest icon from FILEPATH(*.exe)
SHGetFileInfo(FILEPATH, 0, &sfi, sizeof(sfi), SHGFI_SYSICONINDEX);
SHGetImageList(SHIL_JUMBO, IID_IImageList, (void**)&piml);
piml->GetIcon(sfi.iIcon, 0x00000001, &hicon);

// Getting the HBITMAP from it
ICONINFO iconinfo;
GetIconInfo(hicon, &iconinfo);

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

//Creating nessecery palettes for gdi, so i can use Bitmap::FromHBITMAP
PALETTEENTRY pat = { 255,255,255,0 };
LOGPALETTE logpalt = { 0, 1, pat };
HPALETTE hand = CreatePalette(&logpalt);

Bitmap* h = Bitmap::FromHBITMAP(iconinfo.hbmColor, hand);

//Getting image encoders for saving
UINT num, sz;
GetImageEncodersSize(&num, &sz);
ImageCodecInfo* inf = new ImageCodecInfo[sz];
GetImageEncoders(num, sz, inf);
//4 -> png ; 0 -> bitmap
CLSID encoderClsid = inf[4].Clsid;
h->Save(L"PATH_TO_SAVE", &encoderClsid, NULL);
GdiplusShutdown(gdiplusToken);
EN

回答 1

Stack Overflow用户

发布于 2021-09-27 15:31:49

显然,alpha通道包含所有需要的数据,但由于某些原因,它在保存时忽略了alpha通道,修复方法是从以前的位图创建新的位图。

现在,生成的PNG具有透明性。

这是固定的代码。

代码语言:javascript
运行
复制
using namespace Gdiplus;

SHFILEINFO sfi;
IImageList* piml;
HICON hicon;

// Getting the largest icon from FILEPATH(*.exe)
SHGetFileInfo(FILEPATH, 0, &sfi, sizeof(sfi), SHGFI_SYSICONINDEX);
SHGetImageList(SHIL_JUMBO, IID_IImageList, (void**)&piml);
piml->GetIcon(sfi.iIcon, 0x00000001, &hicon);

// Getting the HBITMAP from it
ICONINFO iconinfo;
GetIconInfo(hicon, &iconinfo);

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

//Creating nessecery palettes for gdi, so i can use Bitmap::FromHBITMAP
PALETTEENTRY pat = { 255,255,255,0 };
LOGPALETTE logpalt = { 0, 1, pat };
HPALETTE hand = CreatePalette(&logpalt);

Bitmap* h = Bitmap::FromHBITMAP(iconinfo.hbmColor, hand);

//Getting data from the bitmap and creating new bitmap from it
Rect rect(0, 0, h->GetWidth(), h->GetHeight());
BitmapData bd;
h->LockBits(&rect, ImageLockModeRead, h->GetPixelFormat(), &bd);
Bitmap* newBitmapWithAplha = new Bitmap(bd.Width, bd.Height, bd.Stride, PixelFormat32bppARGB, (BYTE*)bd.Scan0);
h->UnlockBits(&bd);

//Getting image encoders for saving
UINT num, sz;
GetImageEncodersSize(&num, &sz);
ImageCodecInfo* inf = new ImageCodecInfo[sz];
GetImageEncoders(num, sz, inf);
//4 -> png ; 0 -> bitmap
CLSID encoderClsid = inf[4].Clsid;
//Saving the new Bitmap
newBitmapWithAplha->Save(L"PATH_TO_SAVE", &encoderClsid, NULL);
GdiplusShutdown(gdiplusToken);
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69344394

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档