zoukankan      html  css  js  c++  java
  • 提取文件图标,保存为透明图片

    这篇文章介绍一种提取文件或者文件夹的图标的方法,可以保存为背景透明的PNG图标,没有讨厌的黑色背景,嘿嘿。

    1. 首先从文件中提取HICON数据,非常简单

        // 调用方负责DestroyIcon HICON
        HICON GetFileIcon(const CString& strFilePath, BOOL bLarge)
        {
            SHFILEINFO SHFI;
            ZeroMemory(&SHFI, sizeof(SHFI));
            DWORD_PTR ret = ::SHGetFileInfo(strFilePath, 0, &SHFI, sizeof(SHFI), 
                SHGFI_ICON | (bLarge ? SHGFI_LARGEICON : SHGFI_SMALLICON));

            if (ret != 0)
            {
                return SHFI.hIcon;
            }

            return NULL;
        } 

    2. 从HICON中拿出HBITMAP数据,做一些手脚,把它保存成透明的PNG图片

        bool SaveHIcon2PngFile(HICON hIcon, LPCTSTR lpszPicFileName)
        {  
            if (hIcon == NULL)
            {
                return false;
            }

            ICONINFO icInfo = { 0 };    
            if (!::GetIconInfo(hIcon, &icInfo))
            {
                return false;
            }

            BITMAP bitmap; 
            GetObject(icInfo.hbmColor, sizeof(BITMAP), &bitmap);

            Gdiplus::Bitmap* pBitmap = NULL;
            Gdiplus::Bitmap* pWrapBitmap = NULL;
            if (bitmap.bmBitsPixel != 32) 
            {   
                pBitmap = Gdiplus::Bitmap::FromHICON(hIcon); 
            } 
            else
            {
                pWrapBitmap = Gdiplus::Bitmap::FromHBITMAP(icInfo.hbmColor, NULL);
                if (!pWrapBitmap)
                    return false;

                Gdiplus::BitmapData bitmapData;
                Gdiplus::Rect rcImage(0, 0, pWrapBitmap->GetWidth(), pWrapBitmap->GetHeight());
                pWrapBitmap->LockBits(&rcImage, Gdiplus::ImageLockModeRead, pWrapBitmap->GetPixelFormat(), &bitmapData);
                pBitmap = new Gdiplus::Bitmap(bitmapData.Width, bitmapData.Height, bitmapData.Stride, PixelFormat32bppARGB, (BYTE*)bitmapData.Scan0);
                pWrapBitmap->UnlockBits(&bitmapData);
            }

            CLSID encoderCLSID;
            GetEncoderClsid(_T("image/png"), &encoderCLSID);
            Gdiplus::Status st= pBitmap->Save(lpszPicFileName ,&encoderCLSID, NULL/*&encoderParameters*/);
            if( st != Gdiplus::Ok )
                return false;

            delete pBitmap; 
            if (pWrapBitmap)
                delete pWrapBitmap;
            DeleteObject(icInfo.hbmColor); 
            DeleteObject(icInfo.hbmMask);  

            return true;
        }


        int GetEncoderClsid(const WCHAR* format, CLSID* pClsid)
        {
            UINT  num = 0;          // number of image encoders
            UINT  size = 0;         // size of the image encoder array in bytes

            Gdiplus::ImageCodecInfo* pImageCodecInfo = NULL;

            Gdiplus::GetImageEncodersSize(&num, &size);
            if(size == 0)
                return -1;  // Failure

            pImageCodecInfo = (Gdiplus::ImageCodecInfo*)(malloc(size));
            if(pImageCodecInfo == NULL)
                return -1;  // Failure

            GetImageEncoders(num, size, pImageCodecInfo);

            for(UINT j = 0; j < num; ++j)
            {
                if( wcscmp(pImageCodecInfo[j].MimeType, format) == 0 )
                {
                    *pClsid = pImageCodecInfo[j].Clsid;
                    free(pImageCodecInfo);
                    return j;  // Success
                }    
            }

            free(pImageCodecInfo);
            return -1;  // Failure
        }


    3. HICON使用完要记得释放掉

        BOOL SaveFileIcon(const CString& strFilePath, const CString& strImagePath, BOOL bLarge = TRUE)
        {
            BOOL bRet = FALSE;
            HICON hIcon = GetFileIcon(strFilePath, bLarge);
            if (hIcon != NULL)
            {
                bRet = SaveHIcon2PngFile(hIcon, strImagePath);
                ::DestroyIcon(hIcon);
            }

            return bRet;
        }


    上面的代码使用了gdiplus,需要包含gdiplus.h,链接gdiplus.lib,并初始化gdiplus环境(GdiplusStartup)。

    完整的例子可以去这里下载: http://download.csdn.net/source/3525053

  • 相关阅读:
    BZOJ2870 最长道路
    BZOJ1316 树上的询问
    BZOJ2238 Mst
    BZOJ4242 水壶
    [BeiJing2010组队]次小生成树Tree
    CODEVS1403 新三国争霸
    牛客网NOIP赛前集训营-提高组(第六场) C-树
    JSOI2008 最小生成树计数
    BZOJ2654 Tree
    牛客网NOIP赛前集训营-提高组(第六场)B-选择题
  • 原文地址:https://www.cnblogs.com/hzcya1995/p/13318837.html
Copyright © 2011-2022 走看看