【问题标题】:Display Icon in WPF Image在 WPF 图像中显示图标
【发布时间】:2010-06-03 21:11:49
【问题描述】:

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

我发现 here 我可以做到这一点

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

但是当我尝试设置 WPF 图像的来源时,我得到了

"不能将类型'System.Drawing.Icon'隐式转换为'System.Windows.Media.ImageSource'

有什么建议吗?

【问题讨论】:

    标签: c# wpf icons


    【解决方案1】:

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

    【讨论】:

    • 它比位图的建议更简单。感谢您的回答,我将在我的代码中使用它!
    • 对于任何图标模糊的人,请参阅有关 UseLayoutRounding="True" 和/或 RenderOptions.BitmapScalingMode stackoverflow.com/a/2734431/848627 的 stackoverflow 答案
    【解决方案2】:

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

    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中if仍然会显示:

    <x:Static MemberType="{x:Type drawing:SystemIcons}" Member="Asterisk"/>
    

    否则转换器可以在现场使用,如下所示:

    <Image Source="{Binding Source={x:Static drawing:SystemIcons.Asterisk}, 
        Converter={converter:IconToImageSourceConverter}}"/>                
    

    【讨论】:

      【解决方案3】:

      图标在 .NET 框架中不受欢迎。您必须使用 Icon.Save() 将获得的图标保存到 MemoryStream 中。这允许您使用接受流的 IconBitmapDecoder 构造函数。

      【讨论】:

        【解决方案4】:

        我也遇到过类似的问题,通过几个步骤我们就可以得到图片来源:

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

        【讨论】:

        • 不同的图标分辨率(16x16、48x48等)怎么样?有没有办法选择分辨率?
        【解决方案5】:

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2020-06-29
          • 2017-02-18
          • 2012-12-16
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多