2

XLS、XLSX、PDF などの拡張機能のシステム デフォルト アイコン (16 * 16 のみ) を抽出し、それを Image Control に表示しようとしています。これらのアイコンをディスクにダンプすると、それらのアイコンは鮮明に見えますが、ListBox のアイコンはややぼやけて見えます。

ここで何が起こっているのでしょうか?読んだ投稿から多くの提案を試みましたが、問題を解決できませんでした

コードスニペット:

ケース 1 - 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;
}

どんな指針も高く評価されます!

ありがとう

4

3 に答える 3

4

この問題が解決されるまで時間がかかることは承知していますが、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();

私はそれがあなたがしたすべてよりも良いかもしれないと思います.

出典:こちら

于 2016-02-24T05:56:57.733 に答える
1

あなたの質問に対する解決策は次のとおりです。

登録されたファイルの種類とそれに関連付けられたアイコンを C# で取得する

マン・ヴォン製。

于 2012-11-17T07:36:02.087 に答える
1

同様の問題に直面している他の人のために、私の場合に何が助けになったかを共有します。

このプロパティを Image に設定すると、ぼかしを取り除くのに非常に役立ちました。

RenderOptions.BitmapScalingMode="NearestNeighbor"

別のケースでは、20 * 20 のグリッド セルに画像を表示していたため、以下の設定でデフォルトの画像ストレッチを削除することになりました。それも多くの違いをもたらしました。

Stretch = Stretch.None
于 2012-11-21T16:43:56.727 に答える