I'm having trouble adding modern high-resolution, transparent images to a Win32 toolbar. If I get a modern anti-aliased PNG file and convert it to a BMP (using an online conversion tool), and then paste it into Visual Studio's bitmap editor and try to fix the edges myself and then add a black-colored background for transparency (a black mask), there's all kinds of artifacts, the image looks horrible and jagged:
// Create the image list from Bitmap resources with a black mask for transparency
g_hImageList = ImageList_Create(bitmapSize, bitmapSize, // Dimensions of individual bitmaps.
ILC_MASK | ILC_COLORDDB,
numButtons, 0);
HBITMAP hBitmapBtnCut = LoadBitmap(GetModuleHandle(NULL), MAKEINTRESOURCE(IDB_CUT));
HBITMAP hBitmapBtnCopy = LoadBitmap(GetModuleHandle(NULL), MAKEINTRESOURCE(IDB_COPY));
HBITMAP hBitmapBtnPaste = LoadBitmap(GetModuleHandle(NULL), MAKEINTRESOURCE(IDB_PASTE));
ImageList_AddMasked(g_hImageList, hBitmapBtnCut, RGB(0, 0, 0));
ImageList_AddMasked(g_hImageList, hBitmapBtnCopy, RGB(0, 0, 0));
ImageList_AddMasked(g_hImageList, hBitmapBtnPaste, RGB(0, 0, 0));
// Set the image list.
SendMessage(hWndToolbarCutCopyPaste, TB_SETIMAGELIST, (WPARAM)ImageListID, (LPARAM)g_hImageList);
How do people add modern images to toolbars? There was a thread discussing 32-bit bitmaps and PNG for toolbars, but it didn't really provide any good answers. I still have questions:
Why, for 32-bit bitmaps, is it necessary to find and resort to some weird tools like Pixelformer, why don't Paint or VS's own Bitmap Editor provide this? Are 32-bit bitmaps so rare? And would they provide the quality/resolution required? No normal tools support 32-bit bitmaps.
There was a GDI workaround to load PNG images into the toolbar but it failed for me. I pasted the provided code, and not only did it not work, but the app became much slower. I don't want to deal with opening/closing GDI resources and dealing with all that, it slows down the app.
There was no choice but to download Pixelformer per this thread and Save BMP with these settings:
32 BPP
Premultipled Alpha (very important, without this the image won't show up, even if it's 32-BPP!)
Then, this code (note the style LR_CREATEDIBSECTION, also required):
g_hImageList = ImageList_Create(bitmapSize, bitmapSize, // Dimensions of individual bitmaps.
ILC_COLOR32, // Don't need ILC_MASKED because 32-bit Transparent BMPs already have transparency
numButtons, 0);
HBITMAP hBitmapBtnCut = (HBITMAP)LoadImage(GetModuleHandle(NULL), MAKEINTRESOURCE(IDB_CUT), IMAGE_BITMAP, 48, 48, LR_CREATEDIBSECTION);
HBITMAP hBitmapBtnCopy = (HBITMAP)LoadImage(GetModuleHandle(NULL), MAKEINTRESOURCE(IDB_COPY), IMAGE_BITMAP, 48, 48, LR_CREATEDIBSECTION);
HBITMAP hBitmapBtnPaste = (HBITMAP)LoadImage(GetModuleHandle(NULL), MAKEINTRESOURCE(IDB_PASTE), IMAGE_BITMAP, 48, 48, LR_CREATEDIBSECTION);
// Don't need to use ImageList_AddMasked because 32-bit Transparent BMPs already have transparency
ImageList_Add(g_hImageList, hBitmapBtnCut, NULL);
ImageList_Add(g_hImageList, hBitmapBtnCopy, NULL);
ImageList_Add(g_hImageList, hBitmapBtnPaste, NULL);
These advanced bitmaps (in this example, IDB_CUT
, IDB_COPY
, IDB_PASTE
) won't be editable/loadable in VS' Bitmap Editor. In fact they won't even be editable in Paint. Advanced tools like Pixelformer is required. Once you have the final .BMP files, just add them manually to the resource file as follows (this example assumes they're in the same folder):
IDB_CUT BITMAP "ButtonCut.bmp"
IDB_COPY BITMAP "ButtonCopy.bmp"
IDB_PASTE BITMAP "ButtonPaste.bmp"
One note: Before Pixelformer I also tried Paint.NET per a commenter's suggestion. It lets you save 32BPP BMPs, but it doesn't come with Premultipled Alpha, which was still causing blank images for me. There is a Premultipled Alpha plugin for Paint.NET but somehow it doesn't work properly. The image were still blank even after running it and re-saving in Paint.NET. So there was no choice but to use Pixelformer. (And Paint and VS' own Bitmap Editor don't support 32bpp bitmaps.) Very tricky! I'm not even sure what other tools could provide this.