그레이스케일 아이콘 만들기

@codemaru · March 10, 2006 · 4 min read

코드 프로젝트 받은 소스 분석하다 잼써서 올려봅니당...

// This function creates a grayscale icon starting from a given icon.  
// The resulting icon will have the same size of the original one.  
//  
// Parameters:  
//        [IN]    hIcon  
//                Handle to the original icon.  
//  
// Return value:  
//        If the function succeeds, the return value is the handle   
//        to the newly created grayscale icon.  
//        If the function fails, the return value is NULL.  
//  
// Updates:  
//        26/Nov/2002    Restored 1 BitBlt operation  
//        03/May/2002    Removed dependancy from m\_hWnd  
//                    Removed 1 BitBlt operation  
//  
HICON CButtonST::CreateGrayscaleIcon(HICON hIcon)  
{  
    HICON        hGrayIcon = NULL;  
    HDC            hMainDC = NULL, hMemDC1 = NULL, hMemDC2 = NULL;  
    BITMAP        bmp;  
    HBITMAP        hOldBmp1 = NULL, hOldBmp2 = NULL;  
    ICONINFO    csII, csGrayII;  
    BOOL        bRetValue = FALSE;  
  
    bRetValue = ::GetIconInfo(hIcon, &csII);  
    if (bRetValue == FALSE)    return NULL;  
  
    hMainDC = ::GetDC(NULL);  
    hMemDC1 = ::CreateCompatibleDC(hMainDC);  
    hMemDC2 = ::CreateCompatibleDC(hMainDC);  
    if (hMainDC == NULL || hMemDC1 == NULL || hMemDC2 == NULL)      
        return NULL;  
  
    if (::GetObject(csII.hbmColor, sizeof(BITMAP), &bmp))  
    {  
        DWORD    dwWidth = csII.xHotspot\*2;  
        DWORD    dwHeight = csII.yHotspot\*2;  
  
        csGrayII.hbmColor = ::CreateBitmap(dwWidth  
                            , dwHeight  
                            , bmp.bmPlanes  
                            , bmp.bmBitsPixel  
                            , NULL);  
        if (csGrayII.hbmColor)  
        {  
            hOldBmp1 = (HBITMAP)::SelectObject(hMemDC1, csII.hbmColor);  
            hOldBmp2 = (HBITMAP)::SelectObject(hMemDC2, csGrayII.hbmColor);  
  
            DWORD        dwLoopY = 0, dwLoopX = 0;  
            COLORREF    crPixel = 0;  
            BYTE        byNewPixel = 0;  
  
            for (dwLoopY = 0; dwLoopY < dwHeight; dwLoopY++)  
            {  
                for (dwLoopX = 0; dwLoopX < dwWidth; dwLoopX++)  
                {  
                    crPixel = ::GetPixel(hMemDC1, dwLoopX, dwLoopY);  
                    byNewPixel = (BYTE)((GetRValue(crPixel) \* 0.299)   
                                + (GetGValue(crPixel) \* 0.587)   
                                + (GetBValue(crPixel) \* 0.114));  
  
                    if (crPixel)  
                        ::SetPixel(hMemDC2  
                            , dwLoopX  
                            , dwLoopY  
                            , RGB(byNewPixel, byNewPixel, byNewPixel));  
                    else  
                        ::SetPixel(hMemDC2, dwLoopX, dwLoopY, crPixel);  
                } // for  
            } // for  
  
            ::SelectObject(hMemDC1, hOldBmp1);  
            ::SelectObject(hMemDC2, hOldBmp2);  
  
            csGrayII.hbmMask = csII.hbmMask;  
  
            csGrayII.fIcon = TRUE;  
            hGrayIcon = ::CreateIconIndirect(&csGrayII);  
        } // if  
  
        ::DeleteObject(csGrayII.hbmColor);  
        //::DeleteObject(csGrayII.hbmMask);  
    } // if  
  
    ::DeleteObject(csII.hbmColor);  
    ::DeleteObject(csII.hbmMask);  
    ::DeleteDC(hMemDC1);  
    ::DeleteDC(hMemDC2);  
    ::ReleaseDC(NULL, hMainDC);  
  
    return hGrayIcon;  
} // End of CreateGrayscaleIcon
@codemaru
돌아보니 좋은 날도 있었고, 나쁜 날도 있었다. 그런 나의 모든 소소한 일상과 배움을 기록한다. 여기에 기록된 모든 내용은 한 개인의 관점이고 의견이다. 내가 속한 조직과는 1도 상관이 없다.
(C) 2001 YoungJin Shin, 0일째 운영 중