Как конвертировать HICON в HBITMAP в VC ++? - PullRequest
4 голосов
/ 11 сентября 2011

Как конвертировать HICON в HBITMAP в VC ++?

Я знаю, что это часто задаваемые вопросы, но все решения, которые я нашел в 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;
}

Ответы [ 4 ]

7 голосов
/ 23 июня 2012
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;
4 голосов
/ 28 мая 2013

этот код делает это:

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
4 голосов
/ 11 сентября 2011

У меня нет готового кода для совместного использования, но я думаю, что это довольно просто.Вы должны создать HBITMAP, создать контекст устройства, выбрать растровое изображение в DC (это сделает растровое изображение областью рисования для этого DC).Наконец, вызовите функцию DrawIcon (), чтобы нарисовать вашу иконку на этом DC.После этого отсоедините растровое изображение от DC и уничтожьте DC.Теперь ваше растровое изображение должно быть готово к работе.

Обновите, посмотрев на ваш код:

Я полагаю, что проблема в вызове createCompatibleBitmap.Вы запрашиваете битовую карту, совместимую с DC памяти, но DC памяти начинаются с битовой карты 1 бит / пиксель, выбранной в них.Попробуйте вместо этого запросить растровое изображение, совместимое с экраном DC.

Обновление 2: вы можете захотеть взглянуть на этот вопрос , поскольку он кажется связанным с вашей проблемой.

2 голосов
/ 12 августа 2014

Я нашел это (похожий код работает для меня - значки размером 32x32 с альфа-данными или без них):
используется CopyImage (ссылка MSDN)

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 Возможно, для растрового изображения уже установлен альфа-канал * (каждый 4-й байт)! Итак, проверьте это перед тем, как добавить маску к цветным данным.

...