WPF 获取文件夹的缩略图
Posted
技术标签:
【中文标题】WPF 获取文件夹的缩略图【英文标题】:WPF Get Thumbnail of folder 【发布时间】:2020-10-27 01:06:38 【问题描述】:我想获取文件夹的缩略图,但我没有找到任何方法来使用 WPF。对于 UWP,有一个函数 StorageFolder.GetThumbnailAsync()
。但是在 WPF 我没有找到任何解决方案。
【问题讨论】:
看看***.com/a/2994451/1360389也许有帮助。 已经尝试过,但它只适用于文件 你试过ShellFolder
吗?
谢谢,我不敢相信我自己没有弄明白。它只是ShellFolder.FromParsingName(FolderPath).Thumbnail.BitmapSource
它有效,而且它也比 UWP 更好。它还为您提供文件夹的真实缩略图,而不仅仅是默认的空文件夹。将其作为答案发布,以便被接受。
【参考方案1】:
我能够通过 pinvoke 以一种不太干净的方式做到这一点,但它可以正常工作,因为它应该看到代码(使用 GetIcon
方法):
public static class UITools
private const uint FILE_ATTRIBUTE_NORMAL = 0x00000080;
private const uint FILE_ATTRIBUTE_DIRECTORY = 0x00000010;
/// <summary>
/// Converts a <see cref="System.Drawing.Bitmap"/> into a WPF <see cref="BitmapSource"/>.
/// </summary>
/// <remarks>Uses GDI to do the conversion. Hence the call to the marshalled DeleteObject.
/// </remarks>
/// <param name="source">The source bitmap.</param>
/// <returns>A BitmapSource</returns>
public static BitmapSource ToBitmapSource(this System.Drawing.Bitmap source)
BitmapSource bitSrc = null;
var hBitmap = source.GetHbitmap();
try
bitSrc = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(
hBitmap,
IntPtr.Zero,
Int32Rect.Empty,
BitmapSizeOptions.FromEmptyOptions());
catch (Win32Exception)
bitSrc = null;
finally
DeleteObject(hBitmap);
return bitSrc;
public static BitmapSource GetIcon(string path,bool isDirectory)
IntPtr hIcon = GetJumboIcon(GetIconIndex(path,isDirectory));
BitmapSource icon = null;
using (Icon ico = (Icon)System.Drawing.Icon.FromHandle(hIcon).Clone())
icon = ico.ToBitmap().ToBitmapSource();
DestroyIcon(hIcon);
return icon;
internal static int GetIconIndex(string pszFile,bool isDirectory)
uint attributes = FILE_ATTRIBUTE_NORMAL;
if (isDirectory)
attributes |= FILE_ATTRIBUTE_DIRECTORY;
SHFILEINFO sfi = new SHFILEINFO();
NativeMethods.SHGetFileInfo(pszFile
, attributes //0
, ref sfi
, (uint)System.Runtime.InteropServices.Marshal.SizeOf(sfi)
, (uint)(SHGFI.SysIconIndex | SHGFI.LargeIcon | SHGFI.UseFileAttributes));
return sfi.iIcon;
// 256*256
internal static IntPtr GetJumboIcon(int iImage)
IImageList spiml = null;
Guid guil = new Guid(IID_IImageList); //or IID_IImageList2
SHGetImageList(SHIL_EXTRALARGE, ref guil, ref spiml);
IntPtr hIcon = IntPtr.Zero;
spiml.GetIcon(iImage, ILD_TRANSPARENT | ILD_IMAGE, ref hIcon); //
return hIcon;
如您所见,这适用于文件和文件夹。 您可以使用我不久前制作的一个小工具看到它的实际效果: GitHub
【讨论】:
你为什么要传递SHIL_EXTRALARGE
而不是SHIL_JUMBO
(0x0004
)?只是好奇,你的方法被命名为GetJumboIcon()
顺便说一句,还有从hIcon
获取字节数组的方法,因此可以将其传递给IconBitmapDecoder(作为MemoryStream),以从前提中删除System.Drawing
。但那是另一回事了。
@Jimi 我正在尝试使用尺寸标志,SHIL_JUMBO
给了我清晰的图标,但有像素化的边缘和 WPF 抗锯齿并没有帮助我解决这种情况,而SHIL_EXTRALARGE
给了我像jumbo一样清晰但边缘柔和的图标,我当时忘记更改方法名称。
是的,当超大尺寸的图标不可用时会发生这种情况,因此无论如何都会返回超大尺寸 (256x256) 的图标,但它实际上是列表中最大(最后一个)图标,放大到要求的尺寸。您可以向该方法添加一个参数,用户可以在其中以枚举数的形式指定 SHIL_
值(我并不是说您应该在这里更改任何内容,当然,它可以简单地说明一下 - 对于那些谁不知道发生了什么——有什么选择)。 WPF 中的抗锯齿也确实有......它自己的意愿。
@Jimi 谢谢,我不知道放大行为。【参考方案2】:
使用http://***.com/a/2994451/1360389 中提到的Windows API Code Pack 可能会有所帮助。
使用ShellFile.FromFilePath(FilePath).Thumbnail.BitmapSource
文件和
文件夹使用ShellFolder.FromParsingName(FolderPath).Thumbnail.BitmapSource
。
【讨论】:
以上是关于WPF 获取文件夹的缩略图的主要内容,如果未能解决你的问题,请参考以下文章
背水一战 Windows 10 (86) - 文件系统: 获取文件夹的属性, 获取文件夹的缩略图