【问题标题】:WPF C# Extract and Show Default File IconWPF C# 提取并显示默认文件图标
【发布时间】:2016-02-24 13:56:57
【问题描述】:

我正在为某些扩展程序(如 XLS、XLSX、PDF 等)提取系统默认图标(仅限 16 * 16),并尝试在图像控制中显示这些图标。我注意到,如果我将这些图标转储到磁盘上,它们看起来很清晰,但我的 ListBox 中的图标看起来有些模糊。

有什么想法可以在这里发生吗?我从阅读的帖子中尝试了很多建议,但无法解决问题

代码片段:

Case1 - 我正在通过 Win32 Pinvoke 提取文件的图标 - 结果 -> 模糊图标

private const uint SHGFI_ICON = 0x100;
    private const uint SHGFI_LARGEICON = 0x0;
    private const uint SHGFI_SMALLICON = 0x1;
    private const int FILE_ATTRIBUTE_NORMAL = 0x80;
    private const uint SHGFI_USEFILEATTRIBUTES = 0x000000010;
    [StructLayout(LayoutKind.Sequential)]
    private struct SHFILEINFO
    {
        public IntPtr hIcon;
        public IntPtr iIcon;
        public uint dwAttributes;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
        public string szDisplayName;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 80)]
        public string szTypeName;
    };
    [DllImport("shell32.dll")]
    private static extern IntPtr SHGetFileInfo(string pszPath, uint dwFileAttributes,   
   ref SHFILEINFO psfi, uint cbSizeFileInfo, uint uFlags);

private static Icon Extract(string fileName)
{
var shinfo = new SHFILEINFO();

IntPtr hIcon = SHGetFileInfo(fileName, 0, ref shinfo, (uint)Marshal.SizeOf(shinfo), SHGFI_ICON | SHGFI_SMALLICON);
//The icon is returned in the hIcon member of the shinfo struct
var icon = (Icon)Icon.FromHandle(shinfo.hIcon).Clone();
DestroyIcon(shinfo.hIcon);
return icon;
}
[DllImport("User32.dll")]
public static extern int DestroyIcon(IntPtr hIcon);

案例 2 - 将上面创建的图标对象转储到磁盘并在资源管理器中查看它们 -> 图标质量非常好

string filePath = string.Format("C:\\temp\\Icons\\{0}.ico", iconName.Substring(1));
var stream = new FileStream(filePath, FileMode.OpenOrCreate);
iconObject.ExtensionSource.ToBitmap().Save(stream, ImageFormat.Bmp);
stream.Close();

列表框 xaml -

<Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>

        <StackPanel Orientation="Horizontal"
                    Grid.Row="0"
                    Margin="10">
            <TextBox Text="{Binding ExtensionNames, Mode=TwoWay}"
                     ToolTip="Comma Separated List of Extensions, Tab out to persist changes.."
                     Margin="5"/>
            <Button Content="Dump All Icons" 
                    Click="Button_DumpAllIconsClick" 
                    Width="100"
                    ToolTip="Dump Path: C:\temp\Icons"
                    Margin="5"/>

        </StackPanel>
        <ListBox ItemsSource="{Binding Icons}"
                 Grid.Row="1"
                 Margin="2">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <StackPanel Orientation="Horizontal"
                                HorizontalAlignment="Stretch"
                                Margin="5">
                        <TextBlock Text="{Binding ExtensionName}"
                                       FontWeight="Bold"
                                       FontSize="20"/>
                        <Image Source="{Binding Path=ExtensionSource,
                                                Converter={ExtractIconWPF:IconToImageSourceConverter}}"
                               Margin="5"/>
                    </StackPanel>
                </DataTemplate>
            </ListBox.ItemTemplate>
            <ListBox.ItemContainerStyle>
                <Style TargetType="ListBoxItem">
                    <Setter Property="HorizontalContentAlignment" Value="Stretch"/>
                </Style>
            </ListBox.ItemContainerStyle>
        </ListBox>
</Grid>

我如何将 Icon 转换为 ImageSource 对象:

var stream = GetIconStream(iconObject);
ImageSource source = GetBitMapImage(stream);

public static Stream GetIconStream(Icon icon)
{
var iconStream = new MemoryStream();

var bitmap = icon.ToBitmap();
bitmap.Save(iconStream, ImageFormat.Png);

return iconStream;
}

public static ImageSource GetBitMapImage(Stream iconStream)
{
var bi = new BitmapImage();

bi.BeginInit();
bi.StreamSource = iconStream;
bi.EndInit();

return bi;
}

任何指针将不胜感激!

谢谢

【问题讨论】:

    标签: c# wpf icons


    【解决方案1】:

    我知道这个问题已经解决了一段时间,但我看到了一个很酷的 win32 调用快捷方式:

    var sysicon = System.Drawing.Icon.ExtractAssociatedIcon(filePath);
    var bmpSrc = System.Windows.Interop.Imaging.CreateBitmapSourceFromHIcon(
            sysicon.Handle,
            System.Windows.Int32Rect.Empty,
            System.Windows.Media.Imaging.BitmapSizeOptions.FromEmptyOptions());
    sysicon.Dispose();
    

    我认为这可能比你所做的一切都好。

    来源:Here

    【讨论】:

      【解决方案2】:

      以下是您问题的解决方案:

      Get Registered File Types and Their Associated Icons in C#

      Man Vuong 制作。

      【讨论】:

      • 我之前尝试过这种方法,但放弃了这个想法,因为在我的机器上,pdf 是一种注册类型,它无法找到合适的注册表项,所以我对它对用户的可靠性缺乏信心机器。
      【解决方案3】:

      与其他面临类似问题的人分享我的案例。

      在 Image 上设置此属性有助于消除模糊:

      RenderOptions.BitmapScalingMode="NearestNeighbor"
      

      在其他情况下,我们在 20 * 20 的网格单元中显示图像,因此我们最终使用以下设置删除了默认的图像拉伸。这也造成了很大的差异。

      Stretch = Stretch.None
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2010-12-05
        • 2015-02-05
        • 2017-07-26
        • 1970-01-01
        • 2013-07-11
        • 2021-04-10
        • 2012-01-27
        • 1970-01-01
        相关资源
        最近更新 更多