网站已经改版为Wordpress版本,这里是旧版本的快照,请不要在页面中留言.

小悠文件ico提取格式转换辅助类CPEIconHelper,轻松获取文件图标保存到文件

   

     本文出自悠然品鉴小悠,转载请注明出处:http://www.youranshare.com/codeorg/sid/139.html 


    程序中需要一个提取并显示指定文件图标的需求,今天下午也就研究了一下相关的东西,之前一直只能提取出32x32大小的图标文件,画质真心不好,于是就Google了一下老外们的方法研究了一下,最终找到了提取256x265大图标的方法,于是自己就封装了一个类,这里给大家分享一下.


下面的内容会用到一个CLSID的东西,这里先简单的科普一下CLSID的知识:

CLSID是指windows系统对于不同的应用程序,文件类型,OLE对象,特殊文件夹以及各种系统组件分配一个唯一表示它的ID代码,用于对其身份的标示和与其他对象进行区分。

先得说下GUID,它是Globally Unique Identifier的简称,中文翻译为“全局唯一标示符”,在Windows系统中也称之为Class ID,缩写为CLSID。



先简单的说明一下基本的处理流程吧:

   因为用到了GDI+,所以要先初始化GDI+环境

   根据给出的图片保存格式,获取到对应的编码器CLSID(也就是GUID)

   根据给出的文件路径,通过SHGetFileInfo函数获取到ICON的list

   根据给出的保存图片的大小获取到对应图标的句柄

   通过获取到的HICON句柄,创建GDiplus::Bitmap

   通过获取的CLSID和Gdiplus::Bitmap将图片保存到指定的位置

   程序退出,关闭GDI+

 

下面我就来说一下这个CPEIconHelper基本的构成

一、      对应的宏定义

   下面的这四个定义是用于初始化操作的时候的返回值

    //操作过程中 返回的一些 错误信息,函数SetAttribute的返回值
    #define ICON_SUCCESS                    0x00     //初始化成功
    #define ICON_ERRO_CLSID                 0x01     //初始化CLSID出错
    #define ICON_ERRO_HICON                 0x02     //初始化HIcon出错
    #define ICON_ERRO_BITMAP                0x03     //初始化Gdiplus::Bitmap出错


   下面的3个宏定义是指明获取的图标大小

    //图标的大小,分为16/32/256
    #define SIZE_SMALL            SHIL_SMALL     //16x16
    #define SIZE_MID              SHIL_LARGE      //32x32
    #define SIZE_BIG              SHIL_JUMBO     // Vista 之后的 256x256


   下面的5中宏表示了5中不同的格式

    //需要保存的图标 格式
    #define SAVE_BMP               L"image/bmp"
    #define SAVE_JPPEG             L"image/jpeg"
    #define SAVE_PNG               L"image/png"
    #define SAVE_GIF               L"image/gif"
    #define SAVE_TIFF              L"image/tiff"


   下面的这2个宏可以忽略,是类内使用的

    //获取 CLSID|GUID 的值的时候的返回值,类内使用的,无需关心
    #define CLSID_SUCCESS            0x00
    #define CLSID_FAILD              0x01


二、      类内的成员变量

   HICON m_hIcon;//保存 ICO的 句柄

   CLSID m_Clsid;//解码器 GUID | CLSID

   std::string m_szFilePath;//文件路径

   std::wstring m_wszFormat;//文件的格式

   DWORD m_dwWantSize;      //需要获取到的size

   Gdiplus::Bitmap* m_lpBitmap;//保存图片时用到的 Gdi的bitmap


三、      类内的成员函数

   CPEIconHelper();

    ~CPEIconHelper();

这两个是构造函数和析构函数

   DWORD SetFileAttribute(std::string szPath,std::wstring

                                             wszFormat=SAVE_PNG,

DWORD dwWantSize=SIZE_MID);

              这个函数是设置文件的信息的:

              参数1:文件的完整路径

              参数2:需要保存的图片格式,默认PNG

              参数3:需要获取的图片大小,默认是32X32的

              返回值: ICON_SUCCESS、ICON_XXXX这些的,表示初始化的结果

   Gdiplus::Status  SaveToFile(std::wstring wszSavePath);

    这个函数是用于保存操作的,只有当初始化正确后才能调用

    参数1:图标的保存路径,例如C:\test.png

    如果你是Win8系统,保存到系统盘可能有权限的限制,需要管理员权限运行

    返回值: enum Status

{

    Ok = 0,

    GenericError = 1,

    InvalidParameter = 2,

    OutOfMemory = 3,

    ObjectBusy = 4,

    InsufficientBuffer = 5,

    NotImplemented = 6,

    Win32Error = 7,

    WrongState = 8,

    Aborted = 9,

    FileNotFound = 10,

    ValueOverflow = 11,

    AccessDenied = 12,

    UnknownImageFormat = 13,

    FontFamilyNotFound = 14,

    FontStyleNotFound = 15,

    NotTrueTypeFont = 16,

    UnsupportedGdiplusVersion = 17,

    GdiplusNotInitialized = 18,

    PropertyNotFound = 19,

    PropertyNotSupported = 20,

#if (GDIPVER >= 0x0110)

    ProfileNotFound = 21,

#endif //(GDIPVER >= 0x0110)

    };

    描述了保存文件操作的结果.

   bool SetSaveFormat(std::wstring wszNewFmt);

    函数用于重设图片保存的格式

    参数1:新的图片格式

    返回值:true表示成功,false表示失败

   bool SetSaveSize(DWORD dwWantSize);

    函数用于重设保存的图片大小

    参数1:重设的图片大小

        返回值: true表示成功,false表示失败

   int InitEncodersCLSID();

      函数用于初始化解码器的CLSID值,类内自动调用,不可访问

   bool InitHIcon();

    函数用于初始化图标的句柄,类内自动调用,不可访问

   bool InitGBitmap();

    函数用于初始化保存图片用的Gdiplus::Bitmap,类内自动调用,不可访问


四、类内核心

类中的主要核心是通过函数SHGetFileInfo获取到图标的ImageList,然后解析除出需要的Ico句柄,然后调用Gdiplus::Bitmap::FromHICON(m_hIcon);函数创建对应的Gdiplus::Bitmap,然后调用Gdiplus::Bitmap::Save操作保存到对应的图片格式.

这是我的转换执行测试结果:

     

附上示例代码的下载地址: (C++VS2010工程)

解压密码 yscode

百度网盘下载地址:http://pan.baidu.com/s/1qW9F4ZE



  • 标签:
  • exe高清图标提取
  • 文件图标格式转换
  • C++获取文件图标
网站已经改版为Wordpress版本,这里是旧版本的快照,请不要在页面中留言.