【问题标题】:Extracting thumbnail and icon from file in c#从c#中的文件中提取缩略图和图标
【发布时间】:2010-12-22 15:15:49
【问题描述】:

如果缩略图从文件或文件夹(如 Windows 资源管理器)中不可用,我正在尝试提取缩略图或图标。我正在使用 IShellItemImageFactory 并且当缩略图出现时它工作得很好。但是,如果文件没有缩略图,则该方法返回的图标具有黑色背景。

怀疑这是因为当我调用Bitmap.FromHbitmap 将hbitmap 转换为位图时,透明度丢失了。是否可以在不丢失透明度的情况下进行转换?我什至不确定这是否是问题所在。我能找到的唯一参考是对question about IShellItemImageFactory 的评论,上面写着

"API 有时会返回位图 使用预乘 alpha 和 有时使用普通 alpha"

有什么方法可以让图标没有黑色背景,还是在没有缩略图的情况下我应该坚持Icon.ExtractAssociatedIcon

【问题讨论】:

    标签: c# winapi shell com thumbnails


    【解决方案1】:

    我使用以下代码,不确定是否支持透明背景,但您可以尝试一下:

    private const uint SHGFI_ICON           = 0x100;
    private const uint SHGFI_LARGEICON      = 0x0;
    private const uint SHGFI_SMALLICON      = 0x1;
    private const uint SHGFI_DISPLAYNAME    = 0x00000200;
    private const uint SHGFI_TYPENAME       = 0x400;
    
    public static Icon GetSmallFileIcon(this FileInfo file)
    {
        if (file.Exists)
        {
            SHFILEINFO shFileInfo = new SHFILEINFO();
            SHGetFileInfo(file.FullName, 0, ref shFileInfo, (uint)Marshal.SizeOf(shFileInfo), SHGFI_ICON | SHGFI_SMALLICON);
    
            return Icon.FromHandle(shFileInfo.hIcon);
        }
        else return SystemIcons.WinLogo;
    }
    
    public static Icon GetSmallFileIcon(string fileName)
    {
        return GetSmallFileIcon(new FileInfo(fileName));
    }
    
    public static Icon GetLargeFileIcon(this FileInfo file)
    {
        if (file.Exists)
        {
            SHFILEINFO shFileInfo = new SHFILEINFO();
            SHGetFileInfo(file.FullName, 0, ref shFileInfo, (uint)Marshal.SizeOf(shFileInfo), SHGFI_ICON | SHGFI_LARGEICON);
    
            return Icon.FromHandle(shFileInfo.hIcon);
        }
        else return SystemIcons.WinLogo;
    }
    
    public static Icon GetLargeFileIcon(string fileName)
    {
        return GetLargeFileIcon(new FileInfo(fileName));
    }
    
    [StructLayout(LayoutKind.Sequential)]
    public struct SHFILEINFO
    {
        public SHFILEINFO(bool b)
        {
            hIcon = IntPtr.Zero; iIcon = IntPtr.Zero; dwAttributes = 0; szDisplayName = ""; szTypeName = "";
        }
    
        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")]
    public static extern IntPtr SHGetFileInfo(string pszPath, uint dwFileAttributes, ref SHFILEINFO psfi, uint cbSizeFileInfo, uint uFlags);
    

    【讨论】:

    • 感谢 sn-p。实际上我知道 SHGetFileInfo 函数。我只是想避免检查缩略图是否可用,如果不是提取图标。
    【解决方案2】:

    返回的位图有 alpha。它是 32 位,最后 8 位是 alpha。我不确定在您调用 Bitmap.FromHbitmap 时会发生什么,但您可能应该知道,即使 alpha 被正确复制(可能是),您以后也可能不会使用它。如果忽略 alpha,您会看到一个黑框。

    【讨论】:

      猜你喜欢
      • 2010-09-30
      • 2012-05-08
      • 1970-01-01
      • 2017-08-25
      • 2011-04-06
      • 2012-08-04
      • 2013-07-05
      • 2011-08-23
      • 2016-04-05
      相关资源
      最近更新 更多