今天,我做了一个非常好的功能,从Vista图标中提取256x256位图.
和你一样,Nathan W,我用它在"关于"框中将大图标显示为位图.例如,此代码将Vista图标作为PNG图像,并将其显示在256x256 PictureBox中:
picboxAppLogo.Image = ExtractVistaIcon(myIcon);
Run Code Online (Sandbox Code Playgroud)
此函数将Icon对象作为参数.因此,您可以将它与任何图标一起使用 - 来自资源,文件,流等.(请阅读以下有关提取EXE图标的信息).
它可以运行在任何操作系统,因为它并没有使用任何的Win32 API,它是100%托管代码 :-)
// Based on: http://www.codeproject.com/KB/cs/IconExtractor.aspx
// And a hint from: http://www.codeproject.com/KB/cs/IconLib.aspx
Bitmap ExtractVistaIcon(Icon icoIcon)
{
Bitmap bmpPngExtracted = null;
try
{
byte[] srcBuf = null;
using (System.IO.MemoryStream stream = new System.IO.MemoryStream())
{ icoIcon.Save(stream); srcBuf = stream.ToArray(); }
const int SizeICONDIR = 6;
const int SizeICONDIRENTRY = 16;
int iCount = BitConverter.ToInt16(srcBuf, 4);
for (int iIndex=0; iIndex<iCount; iIndex++)
{
int iWidth = srcBuf[SizeICONDIR + SizeICONDIRENTRY * iIndex];
int iHeight = srcBuf[SizeICONDIR + SizeICONDIRENTRY * iIndex + 1];
int iBitCount = BitConverter.ToInt16(srcBuf, SizeICONDIR + SizeICONDIRENTRY * iIndex + 6);
if (iWidth == 0 && iHeight == 0 && iBitCount == 32)
{
int iImageSize = BitConverter.ToInt32(srcBuf, SizeICONDIR + SizeICONDIRENTRY * iIndex + 8);
int iImageOffset = BitConverter.ToInt32(srcBuf, SizeICONDIR + SizeICONDIRENTRY * iIndex + 12);
System.IO.MemoryStream destStream = new System.IO.MemoryStream();
System.IO.BinaryWriter writer = new System.IO.BinaryWriter(destStream);
writer.Write(srcBuf, iImageOffset, iImageSize);
destStream.Seek(0, System.IO.SeekOrigin.Begin);
bmpPngExtracted = new Bitmap(destStream); // This is PNG! :)
break;
}
}
}
catch { return null; }
return bmpPngExtracted;
}
Run Code Online (Sandbox Code Playgroud)
重要!如果你想直接从EXE文件加载这个图标,那么你不能使用Icon.ExtractAssociatedIcon(Application.ExecutablePath)作为参数,因为.NET函数ExtractAssociatedIcon()是如此愚蠢,它只提取32x32图标!
相反,您最好使用由Tsuda Kageyu(http://www.codeproject.com/KB/cs/IconExtractor.aspx)创建的整个IconExtractor类.您可以稍微简化此类,以使其更小.以这种方式使用IconExtractor:
// Getting FILL icon set from EXE, and extracting 256x256 version for logo...
using (TKageyu.Utils.IconExtractor IconEx = new TKageyu.Utils.IconExtractor(Application.ExecutablePath))
{
Icon icoAppIcon = IconEx.GetIcon(0); // Because standard System.Drawing.Icon.ExtractAssociatedIcon() returns ONLY 32x32.
picboxAppLogo.Image = ExtractVistaIcon(icoAppIcon);
}
Run Code Online (Sandbox Code Playgroud)
注意:我在这里仍然使用我的ExtractVistaIcon()函数,因为我不喜欢IconExtractor如何处理这个工作 - 首先,它通过使用IconExtractor.SplitIcon(icoAppIcon)提取所有图标格式,然后你必须知道确切的256x256图标索引,以获得所需的vista图标.所以,使用我的ExtractVistaIcon()在这里更快更简单的方式:)