Reputation: 31
Im trying to get and icon from and exe and save it as png with transparency. i've been able to get the bitmap from it with gdi+ and save the .bmp with the correct alpha channel(checked in Photoshop). but now the problem is that when i want to save it as .png, the transparency will not transfer to the file (transpaernt areas are black) here's my code:
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);
Upvotes: 1
Views: 824
Reputation: 31
So apparently the alpha channel is there with all the data needed but for some reason it ignores the alpha channel upon saving and the Fix for that is to create new Bitmap from the previous bitmap.
now the resulting PNG has transparency.
here is the fixed code.
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);
Upvotes: 2