Конвертируем иконку 32x32 в 16x16

Для решения такой задачи, берём два битмапа иконки (битмап самой картинки и битмап маски) и изменяем размер каждого битмапа отдельно с 32x32 до 16x16. Из двух новых битмапов, полученных путём преобразования легко можно сделать новую иконку 16x16. Теоретически, процедура работает правильно, однако, я заметил, что сама Windows преобразовывает более качественно.

HICON Convert32x32IconTo16x16(HICON h32x32Icon)
{
HDC hMainDC, hMemDC1, hMemDC2;
HICON h16x16Icon;
BITMAP bmp;
HBITMAP hOldBmp1, hOldBmp2;
ICONINFO IconInfo32x32, IconInfo16x16;

GetIconInfo(h32x32Icon, &IconInfo32x32);

hMainDC = ::GetDC(m_hWnd);
hMemDC1 = CreateCompatibleDC(hMainDC);
hMemDC2 = CreateCompatibleDC(hMainDC);

GetObject(IconInfo32x32.hbmColor, sizeof(BITMAP), &bmp);

IconInfo16x16.hbmColor = CreateBitmap( 16, 16,
bmp.bmPlanes,
bmp.bmBitsPixel,
NULL);

hOldBmp1 = (HBITMAP) SelectObject( hMemDC1,
IconInfo32x32.hbmColor);
hOldBmp2 = (HBITMAP) SelectObject( hMemDC2,
IconInfo16x16.hbmColor);

StretchBlt(hMemDC2,
0, 0,
16, 16,
hMemDC1,
0, 0,
32, 32,
SRCCOPY
);

GetObject(IconInfo32x32.hbmMask, sizeof(BITMAP), &bmp);

IconInfo16x16.hbmMask = CreateBitmap( 16, 16,
bmp.bmPlanes,
bmp.bmBitsPixel,
NULL);

SelectObject(hMemDC1, IconInfo32x32.hbmMask);
SelectObject(hMemDC2, IconInfo16x16.hbmMask);

StretchBlt(hMemDC2,
0, 0,
16, 16,
hMemDC1,
0, 0,
32, 32,
SRCCOPY
);

SelectObject(hMemDC1, hOldBmp1);
SelectObject(hMemDC2, hOldBmp2);

IconInfo16x16.fIcon = TRUE;
h16x16Icon = CreateIconIndirect(&IconInfo16x16);

DeleteObject(IconInfo32x32.hbmColor);
DeleteObject(IconInfo16x16.hbmColor);
DeleteObject(IconInfo32x32.hbmMask);
DeleteObject(IconInfo16x16.hbmMask);
DeleteDC(hMemDC1);
DeleteDC(hMemDC2);
::ReleaseDC(m_hWnd, hMainDC);

return h16x16Icon;
 
« Предыдущая статья   Следующая статья »