在WPF图像中显示图标

22

我有一个 WPF 应用程序,需要从可执行文件中提取图标。

我在这里发现我可以这样做。

Icon ico = Icon.ExtractAssociatedIcon(theProcess.MainModule.FileName);

但当我尝试设置WPF Image的源时,出现了以下错误:

"无法隐式转换类型'System.Drawing.Icon'为'System.Windows.Media.ImageSource'

有什么建议吗?

5个回答

17

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());
}

这比使用位图更简单。感谢您的答案,我会在我的代码中使用它! - ASh
对于那些出现模糊图标的人,请参考这个 stackoverflow 答案,了解 UseLayoutRounding="True" 和/或 RenderOptions.BitmapScalingMode https://dev59.com/InRB5IYBdhLWcg3wiHz7#2734431。 - drojf

13

我想提供我想出的解决方案:

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}}"/>                

11

在.NET框架中,图标很少被使用。您需要使用Icon.Save()函数将获取到的图标保存到MemoryStream中,以便使用带有流参数的IconBitmapDecoder构造函数。


5

我曾经遇到过类似的问题,通过以下几个步骤,我们可以获取图片源代码:

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);
}

我们可以使用此图像源来填充 XAML 中的属性源:
 <Image Source="{Binding Path=ImageSource, Mode=OneTime}" />

6
不同的图标分辨率(例如16x16、48x48等)怎么办?有没有选择分辨率的方法? - bytecode77

0
我使用这个扩展方法将图标转换为ImageSource:
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();

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接