Search code examples
c++listviewwinapiimagelist

HICON loaded with Gdiplus from PNG has low quality


I am trying to load a few PNG images into an WinAPI ImageList, as icons for the elements to show in a ListView. I do this with Gdiplus and the problem I have is that the quality is awful. Is like the color depth is reduced or something.

This is how I do it (in a function called from WinMain, just before the loop):

HIMAGELIST hLarge;
HIMAGELIST hSmall;

hLarge = ImageList_Create(GetSystemMetrics(SM_CXICON),
    GetSystemMetrics(SM_CYICON),
    ILC_MASK, 1, 1);

hSmall = ImageList_Create(GetSystemMetrics(SM_CXSMICON),
    GetSystemMetrics(SM_CYSMICON),
    ILC_MASK, 1, 1);

ListView_SetImageList(hWndListView, hLarge, LVSIL_NORMAL);
ListView_SetImageList(hWndListView, hSmall, LVSIL_SMALL);

HICON hIconItem
Gdiplus::Bitmap *bitmap = new Gdiplus::Bitmap(image_path, 0);
bitmap->GetHICON(&hIconItem);
ImageList_AddIcon(hSmall, hiconItem);
ImageList_AddIcon(hLarge, hiconItem);

Now, what am I missing and where does the image loose information?

This is how icons show up and below the real icons (in PNG)

I have changed ILC_MASK to ILC_MASK | ILC_COLOR32. The quality is a little better but there's no anti-alias.


Solution

  • Your PNG is very likely 32-bit color. In your ImageList_Create() calls, use the flags ILC_COLOR32 | ILC_MASK, not ILC_MASK only.

    According to MSDN, if you don't specify one of the ILC_COLORxxx flags, it defaults to ILC_COLOR4, which is 4-bit 16 color graphics. This explains your reduced image quality. Explicitly specifying ILC_COLOR32 will give you the full-color icons you want.