如何在VC ++中将HICON转换为HBITMAP?
我知道这是一个常见问题,但我在Google上找到的所有解决方案都不起作用。我需要的是一个带参数HICON并返回HBITMAP的函数。
如果可能的话,最好转换为32位位图,即使图标是24位,16位或8位。
这是代码,我不知道它出错的地方:
HBITMAP icon_to_bitmap(HICON Icon_Handle) {
HDC Screen_Handle = GetDC(NULL);
HDC Device_Handle = CreateCompatibleDC(Screen_Handle);
HBITMAP Bitmap_Handle =
CreateCompatibleBitmap(Device_Handle,GetSystemMetrics(SM_CXICON),
GetSystemMetrics(SM_CYICON));
HBITMAP Old_Bitmap = (HBITMAP)SelectObject(Device_Handle,Bitmap_Handle);
DrawIcon(Device_Handle, 0,0, Icon_Handle);
SelectObject(Device_Handle,Old_Bitmap);
DeleteDC(Device_Handle);
ReleaseDC(NULL,Screen_Handle);
return Bitmap_Handle;
}
答案 0 :(得分:7)
HDC hDC = GetDC(NULL);
HDC hMemDC = CreateCompatibleDC(hDC);
HBITMAP hMemBmp = CreateCompatibleBitmap(hDC, x, y);
HBITMAP hResultBmp = NULL;
HGDIOBJ hOrgBMP = SelectObject(hMemDC, hMemBmp);
DrawIconEx(hMemDC, 0, 0, hIcon, x, y, 0, NULL, DI_NORMAL);
hResultBmp = hMemBmp;
hMemBmp = NULL;
SelectObject(hMemDC, hOrgBMP);
DeleteDC(hMemDC);
ReleaseDC(NULL, hDC);
DestroyIcon(hIcon);
return hResultBmp;
答案 1 :(得分:4)
我没有可供分享的代码,但我认为这很容易。您必须创建HBITMAP,创建设备上下文,在DC中选择位图(这将使位图成为此DC的绘图区域)。最后调用DrawIcon()函数在此DC上绘制图标。之后,从DC分离位图并销毁DC。你的位图现在应该准备好了。
查看代码后更新:
我认为问题出在createCompatibleBitmap调用中。您要求与内存DC兼容的位图,但内存DC以选择的1位/像素位图开始。请尝试寻求与屏幕DC兼容的位图。
更新2:您可能希望查看this question,因为它似乎与您的问题有关。
答案 2 :(得分:4)
此代码执行此操作:
HICON hIcon = (HICON)LoadImage(instance, MAKEINTRESOURCEW(IDI_ICON), IMAGE_ICON, width, height, 0);
ICONINFO iconinfo;
GetIconInfo(hIcon, &iconinfo);
HBITMAP hBitmap = iconinfo.hbmColor;
这是* .rc文件中的代码:
IDI_ICON ICON "example.ico"
这是* .h文件中的代码:
#define IDI_ICON 4000
答案 3 :(得分:2)
我发现了这个(类似的代码适用于我 - 带或不带alpha数据的32x32图标):
使用CopyImage (msdn link)
HICON hICON = /*your code here*/
HBITMAP hBITMAPcopy;
ICONINFOEX IconInfo;
BITMAP BM_32_bit_color;
BITMAP BM_1_bit_mask;
// 1. From HICON to HBITMAP for color and mask separately
//.cbSize required
//memset((void*)&IconInfo, 0, sizeof(ICONINFOEX));
IconInfo.cbSize = sizeof(ICONINFOEX);
GetIconInfoEx( hICON , &IconInfo);
//HBITMAP IconInfo.hbmColor is 32bit per pxl, however alpha bytes can be zeroed or can be not.
//HBITMAP IconInfo.hbmMask is 1bit per pxl
// 2. From HBITMAP to BITMAP for color
// (HBITMAP without raw data -> HBITMAP with raw data)
// LR_CREATEDIBSECTION - DIB section will be created,
// so .bmBits pointer will not be null
hBITMAPcopy = (HBITMAP)CopyImage(IconInfo.hbmColor, IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION);
// (HBITMAP to BITMAP)
GetObject(hBITMAPcopy, sizeof(BITMAP), &BM_32_bit_color);
//Now: BM_32_bit_color.bmBits pointing to BGRA data.(.bmWidth * .bmHeight * (.bmBitsPixel/8))
// 3. From HBITMAP to BITMAP for mask
hBITMAPcopy = (HBITMAP)CopyImage(IconInfo.hbmMask, IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION);
GetObject(hBITMAPcopy, sizeof(BITMAP), &BM_1_bit_mask);
//Now: BM_1_bit_mask.bmBits pointing to mask data (.bmWidth * .bmHeight Bits!)
BM_32_bit_color 位图可能已经设置了Alpha *通道*(每个第4个字节)!所以 - 在将掩码位添加到颜色数据之前检查它。