您的位置:首页 > 其它

[一分钟学会系列之五]一分钟学会提取文件图标,保存为透明图片(附DEMO程序)

2011-08-08 09:10 369 查看
这篇文章介绍一种提取文件或者文件夹的图标的方法,可以保存为背景透明的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

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐