我有一个 WPF 应用程序,需要从可执行文件中提取图标。
我在这里发现我可以这样做。
Icon ico = Icon.ExtractAssociatedIcon(theProcess.MainModule.FileName);
但当我尝试设置WPF Image的源时,出现了以下错误:
"无法隐式转换类型'System.Drawing.Icon'为'System.Windows.Media.ImageSource'
有什么建议吗?
System.Windows.Interop.Imaging.CreateBitmapSourceFromHIcon
方法可以用于将System.Drawing.Icon
转换为wpf BitmapSource
。
using(Icon ico = Icon.ExtractAssociatedIcon(theProcess.MainModule.FileName))
{
image.Source = Imaging.CreateBitmapSourceFromHIcon(ico.Handle, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());
}
我想提供我想出的解决方案:
public static class IconExtensions
{
[DllImport("gdi32.dll", SetLastError = true)]
private static extern bool DeleteObject(IntPtr hObject);
public static ImageSource ToImageSource(this Icon icon)
{
Bitmap bitmap = icon.ToBitmap();
IntPtr hBitmap = bitmap.GetHbitmap();
ImageSource wpfBitmap = Imaging.CreateBitmapSourceFromHBitmap(
hBitmap,
IntPtr.Zero,
Int32Rect.Empty,
BitmapSizeOptions.FromEmptyOptions());
if (!DeleteObject(hBitmap))
{
throw new Win32Exception();
}
return wpfBitmap;
}
}
然后我有一个IconToImageSourceConverter,它只是调用上面的方法。
为了让我更容易地将图标添加为图像,我还添加了这个:
<DataTemplate DataType="{x:Type drawing:Icon}">
<Image Source="{Binding Converter={converter:IconToImageSourceConverter}}"
MaxWidth="{Binding Width}" MaxHeight="{Binding Height}"/>
</DataTemplate>
如果将图标直接放在XAML中,它仍然会显示:
<x:Static MemberType="{x:Type drawing:SystemIcons}" Member="Asterisk"/>
否则,转换器可以在现场使用,如下所示:<Image Source="{Binding Source={x:Static drawing:SystemIcons.Asterisk},
Converter={converter:IconToImageSourceConverter}}"/>
在.NET框架中,图标很少被使用。您需要使用Icon.Save()函数将获取到的图标保存到MemoryStream中,以便使用带有流参数的IconBitmapDecoder构造函数。
我曾经遇到过类似的问题,通过以下几个步骤,我们可以获取图片源代码:
ImageSource imageSource;
Icon icon = Icon.ExtractAssociatedIcon(path);
using (Bitmap bmp = icon.ToBitmap())
{
var stream = new MemoryStream();
bmp.Save(stream, System.Drawing.Imaging.ImageFormat.Png);
imageSource = BitmapFrame.Create(stream);
}
<Image Source="{Binding Path=ImageSource, Mode=OneTime}" />
public static System.Windows.Media.ImageSource ToWpfImageSource(this System.Drawing.Icon icon)
{
using (MemoryStream strm = new MemoryStream())
{
icon.Save(strm);
return System.Windows.Media.Imaging.BitmapFrame.Create(strm, System.Windows.Media.Imaging.BitmapCreateOptions.None, System.Windows.Media.Imaging.BitmapCacheOption.OnLoad);
}
}
...
Icon icon = Icon.ExtractAssociatedIcon(path);
ImageSouce imageWpf = icon.ToWpfImageSource();