Windows资源管理器可以显示文件的缩略图。这些缩略图由核心和第三方shell扩展提供。
我知道如何扩展shell以向Windows提供缩略图。
我想要做的是使用C#通过shell从系统上的任何文件中检索缩略图。这可能吗?
基本上,我正在编写一个自定义文件浏览器,我想显示缩略图,并且无法解析地球上的每个文件以制作我自己的缩略图。
澄清: 许多答案似乎都围绕网页缩略图或缩放图像。但这根本不是我想要的。我想要的是向Windows询问这些文件类型的缩略图:.DOC,.PDF,.3DM,.DWG ......和mabye大约十几个。我不想自己解析,渲染和制作缩略图,因为Windows已经知道如何了。
我作为答案发布的代码实际上有用......也许它可以简化并清理一下。
答案 0 :(得分:75)
今天跑过这个 - 它已经有几个月了,但它完成了我的工作(在Win7上,提取MPEG-4文件的缩略图):
代码:
ShellFile shellFile = ShellFile.FromFilePath(pathToYourFile);
Bitmap shellThumb = shellFile.Thumbnail.ExtraLargeBitmap;
希望它有所帮助!
答案 1 :(得分:18)
SharePoint中的Microsoft Office缩略图 http://msdn.microsoft.com/en-us/library/aa289172(VS.71).aspx。正是您想要的。 (我使用http://www.developerfusion.com/tools/convert/vb-to-csharp/将VB.NET代码转换为C#没有问题。)
关于您在答案中发布的代码,http://www.vbaccelerator.com/home/net/code/libraries/Shell_Projects/Thumbnail_Extraction/article.asp上的使用命令行管理程序提取缩略图是代码来自的原始文章。我相信几乎所有IExtractImage
个样本(您找到的搜索)都是基于本文的代码,因为命名约定,注释等是从原始代码中提取的。由于本文发布于2003年4月,因此它带有一些非标准(非.NET)编码约定。我做了一些基本测试,还有垃圾收集问题,解决了非托管资源问题以及其他清理问题。因此,我强烈建议避免该文章中的代码。而且,代码的结构是一种使维护变得困难的方法。
2005年7月在MSDN上有一个简洁的简洁版本,在http://msdn.microsoft.com/en-us/library/aa289172(VS.71).aspx名为 Microsoft Office缩略图在SharePoint 中。此代码和文章的代码共享相似之处让我相信缩略图提取使用Shell 文章是 SharePoint 文章的基础。 VB.NET版本的GetThumbnailImage
忽略longestEdge
参数,但C ++版本使用它并记录ORIGSIZE
和QUALITY
标志的使用。此外,该代码说明了如何使用.NET FreeCoTaskMem
而不是Shell的IMalloc
和SHGetMalloc
。
IExtractImage
适用于文件,文件夹和其他命名空间对象。 MSDN代码使用隐藏文件,而vbAccelerator代码需要SHCONTF_INCLUDEHIDDEN
添加到EnumObjects
调用。此外,vbAccelerator枚举shell文件夹的对象以查找指定的文件,这似乎是浪费时间。可能需要这样才能找到用于GetUIObjectOf
调用的正确“相对”PIDL。
在http://cid-7178d2c79ba0a7e3.office.live.com/self.aspx/.Public/ShellThumbnail.zip完成示例项目。
Imports System.Runtime.InteropServices
Namespace Shell
''' <summary>
''' Generates a thumbnail of a folder's picture or a file's image.
''' </summary>
''' <remarks>This is the "Folder's Picture" and not the "Folder's Icon"! Use SHGetFileInfo to generate the thumbnail for a folder's icon or for a file that does not have a thumbnail handler.</remarks>
''' <reference>Microsoft Office Thumbnails in SharePoint at http://msdn.microsoft.com/en-us/library/aa289172%28VS.71%29.aspx.</reference>
Public Class ShellThumbnail
'TODO - Work out the details for image size and IEIFLAG handling.
#Region " Determining Thumbnail Size and Quality [documentation] "
'http://support.microsoft.com/kb/835823
'Determining Thumbnail Size and Quality
'Browse to HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer. Create or modify two DWORDs called ThumbnailSize and ThumbnailQuality. For ThumbnailSize set the value in pixels, with the default being 96. For ThumbnailQuality set the value as a number that represents the percentage quality between 50 and 100.
'http://www.pctools.com/guides/registry/detail/1066/ (modified)
' User Key: [HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer]
'System Key: [HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Explorer]
'Value Name: ThumbnailSize, ThumbnailQuality
' Data Type: REG_DWORD (DWORD Value)
'Value Data: Size in pixels (32-255), Quality Percentage (50-100)
'Microsoft® Windows® XP Registry Guide
'Jerry Honeycutt
'09/11/2002
'Microsoft Press
'http://www.microsoft.com/mspress/books/sampchap/6232.aspx#118
'<H3><I><A name=118></A>Thumbnails</I></H3>The Thumbnails category controls the
'quality of thumbnails in Windows Explorer. Table 5-10 describes the values for
'Image Quality and Size. Create values that you don't see in the registry. The
'default value for <CODE>ThumbnailQuality</CODE> is <CODE>0x5A</CODE>. The
'default value for <CODE>ThumbnailSize</CODE> is <CODE>0x60</CODE>. Keep in mind
'that higher quality and larger thumbnails require more disk space, which is not
'usually a problem, but they also take longer to display. Changing the quality
'does not affect thumbnails that already exist on the file system.
'<P><B>Table 5-10 </B><I>Values in Thumbnails</I>
'<P>
'<TABLE border=0 cellSpacing=1 cellPadding=4 width="100%">
'<TBODY>
'<TR>
'<TD bgColor=#999999 vAlign=top><B>Setting</B></TD>
'<TD bgColor=#999999 vAlign=top><B>Name</B></TD>
'<TD bgColor=#999999 vAlign=top><B>Type</B></TD>
'<TD bgColor=#999999 vAlign=top><B>Data</B></TD></TR>
'<TR>
'<TD bgColor=#cccccc
'vAlign=top><CODE><B>HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer</B></CODE></TD>
'<TD bgColor=#cccccc vAlign=top> </TD>
'<TD bgColor=#cccccc vAlign=top> </TD>
'<TD bgColor=#cccccc vAlign=top> </TD></TR>
'<TR>
'<TD bgColor=#cccccc vAlign=top><CODE>Image Quality</CODE></TD>
'<TD bgColor=#cccccc vAlign=top><CODE>ThumbnailQuality</CODE></TD>
'<TD bgColor=#cccccc vAlign=top><CODE>REG_DWORD</CODE></TD>
'<TD bgColor=#cccccc vAlign=top><CODE>0x32 - 0x64</CODE></TD></TR>
'<TR>
'<TD bgColor=#cccccc vAlign=top><CODE>Size (pixels)</CODE></TD>
'<TD bgColor=#cccccc vAlign=top><CODE>ThumbnailSize</CODE></TD>
'<TD bgColor=#cccccc vAlign=top><CODE>REG_DWORD</CODE></TD>
'<TD bgColor=#cccccc vAlign=top><CODE>0x20 - 0xFF</CODE></TD></TR></TBODY></TABLE></P>
#End Region
Public Shared ReadOnly DefaultThumbnailSize As New System.Drawing.Size(96, 96)
Public Const DefaultColorDepth As Integer = 32
''' <summary>
''' Used to request an image from an object, such as an item in a Shell folder.
''' </summary>
''' <param name="path">An absolute path to a file or folder.</param>
Public Shared Function ExtractImage(ByVal path As String) As Bitmap
Return ExtractImage(path, System.Drawing.Size.Empty, DefaultColorDepth, 0)
End Function
''' <summary>
''' Used to request an image from an object, such as an item in a Shell folder.
''' </summary>
''' <param name="path">An absolute path to a file or folder.</param>
''' <param name="size"></param>
Public Shared Function ExtractImage(ByVal path As String, ByVal size As System.Drawing.Size) As Bitmap
Return ExtractImage(path, size, DefaultColorDepth, 0)
End Function
''' <summary>
''' Used to request an image from an object, such as an item in a Shell folder.
''' </summary>
''' <param name="path">An absolute path to a file or folder.</param>
''' <param name="size"></param>
''' <param name="recommendedColorDepth">The recommended color depth in units of bits per pixel. The default is 32.</param>
Public Shared Function ExtractImage(ByVal path As String, ByVal size As System.Drawing.Size, ByVal recommendedColorDepth As Integer) As Bitmap
Return ExtractImage(path, size, recommendedColorDepth, 0)
End Function
''' <summary>
''' Used to request an image from an object, such as an item in a Shell folder.
''' </summary>
''' <param name="path">An absolute path to a file or folder.</param>
''' <param name="size"></param>
''' <param name="recommendedColorDepth">The recommended color depth in units of bits per pixel. The default is 32.</param>
Private Shared Function ExtractImage(ByVal path As String, ByVal size As System.Drawing.Size, ByVal recommendedColorDepth As Integer, ByVal flags As IEIFLAG) As Bitmap
Dim oResult As Bitmap = Nothing
Dim oDesktopFolder As IShellFolder = Nothing
Dim hParentIDL As IntPtr
Dim hIDL As IntPtr
Dim oParentFolder As IShellFolder
Dim hParentFolder As IntPtr
Dim oExtractImage As IExtractImage
Dim hExtractImage As IntPtr
'Divide the file name into a path and file/folder name.
Dim sFolderName As String = System.IO.Path.GetDirectoryName(path)
Dim sBaseName As String = System.IO.Path.GetFileName(path)
'Get the desktop IShellFolder.
If SHGetDesktopFolder(oDesktopFolder) <> Missico.Win32.S_OK Then
Throw New System.Runtime.InteropServices.COMException
End If
'Get the parent folder for the specified path.
oDesktopFolder.ParseDisplayName(IntPtr.Zero, IntPtr.Zero, sFolderName, 0, hParentIDL, 0)
oDesktopFolder.BindToObject(hParentIDL, IntPtr.Zero, ShellGUIDs.IID_IShellFolder, hParentFolder)
oParentFolder = CType(Marshal.GetTypedObjectForIUnknown(hParentFolder, GetType(IShellFolder)), IShellFolder)
'Get the file/folder's IExtractImage
oParentFolder.ParseDisplayName(IntPtr.Zero, IntPtr.Zero, sBaseName, 0, hIDL, 0)
oParentFolder.GetUIObjectOf(IntPtr.Zero, 1, New IntPtr() {hIDL}, ShellGUIDs.IID_IExtractImage, IntPtr.Zero, hExtractImage)
'Free the pidls. The Runtime Callable Wrappers (RCW) should automatically release the COM objects.
Marshal.FreeCoTaskMem(hParentIDL)
Marshal.FreeCoTaskMem(hIDL)
Marshal.FinalReleaseComObject(oParentFolder)
Marshal.FinalReleaseComObject(oDesktopFolder)
If hExtractImage = IntPtr.Zero Then
'There is no handler for this file, which is odd. I believe we should default the file's type icon.
Debug.WriteLine(String.Format("There is no thumbnail for the specified file '{0}'.", path), "ShellThumbnail.ExtractImage")
Else
oExtractImage = CType(Marshal.GetTypedObjectForIUnknown(hExtractImage, GetType(IExtractImage)), IExtractImage)
'Set the size and flags
Dim oSize As Missico.Win32.SIZE 'must specify a size
Dim iFlags As IEIFLAG = flags Or IEIFLAG.IEIFLAG_ORIGSIZE Or IEIFLAG.IEIFLAG_QUALITY Or IEIFLAG.IEIFLAG_ASPECT
If size.IsEmpty Then
oSize.cx = DefaultThumbnailSize.Width
oSize.cy = DefaultThumbnailSize.Height
Else
oSize.cx = size.Width
oSize.cy = size.Height
End If
Dim hBitmap As IntPtr
Dim sPath As New System.Text.StringBuilder(Missico.Win32.MAX_PATH, Missico.Win32.MAX_PATH)
oExtractImage.GetLocation(sPath, sPath.Capacity, 0, oSize, recommendedColorDepth, iFlags)
'if the specified path is to a folder then IExtractImage.Extract fails.
Try
oExtractImage.Extract(hBitmap)
Catch ex As System.Runtime.InteropServices.COMException
'clear the handle since extract failed
hBitmap = IntPtr.Zero
Debug.WriteLine(String.Format("There is no thumbnail for the specified folder '{0}'.", path), "ShellThumbnail.ExtractImage")
Finally
Marshal.FinalReleaseComObject(oExtractImage)
End Try
If Not hBitmap.Equals(IntPtr.Zero) Then
'create the image from the handle
oResult = System.Drawing.Bitmap.FromHbitmap(hBitmap)
'dump the properties to determine what kind of bitmap is returned
'Missico.Diagnostics.ObjectDumper.Write(oResult)
'Tag={ }
'PhysicalDimension={Width=96, Height=96}
'Size={Width=96, Height=96}
'Width=96
'Height=96
'HorizontalResolution=96
'VerticalResolution=96
'Flags=335888
'RawFormat={ }
'PixelFormat=Format32bppRgb
'Palette={ }
'FrameDimensionsList=...
'PropertyIdList=...
'PropertyItems=...
Missico.Win32.DeleteObject(hBitmap) 'release the handle
End If
End If
Return oResult
End Function
End Class
End Namespace
答案 2 :(得分:7)
这可能有所帮助:
这包括Shell API,并允许您几乎完成shell的所有操作(包括渲染缩略图)。
答案 3 :(得分:3)
这是我在互联网上搜索的课程。看起来原始代码来自http://www.experts-exchange.com/Programming/Languages/C_Sharp/Q_21789724.html,但我无法看到它给出正确的归属。我在这里找到了来源:http://www.vbforums.com/showthread.php?t=527704
这是一个有适当COM调用的类,这里为后代再现:
using System;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Runtime.InteropServices;
using System.Text;
namespace RMA.Shell
{
public class ShellThumbnail : IDisposable
{
[Flags]
private enum ESTRRET
{
STRRET_WSTR = 0,
STRRET_OFFSET = 1,
STRRET_CSTR = 2
}
[Flags]
private enum ESHCONTF
{
SHCONTF_FOLDERS = 32,
SHCONTF_NONFOLDERS = 64,
SHCONTF_INCLUDEHIDDEN = 128,
}
[Flags]
private enum ESHGDN
{
SHGDN_NORMAL = 0,
SHGDN_INFOLDER = 1,
SHGDN_FORADDRESSBAR = 16384,
SHGDN_FORPARSING = 32768
}
[Flags]
private enum ESFGAO
{
SFGAO_CANCOPY = 1,
SFGAO_CANMOVE = 2,
SFGAO_CANLINK = 4,
SFGAO_CANRENAME = 16,
SFGAO_CANDELETE = 32,
SFGAO_HASPROPSHEET = 64,
SFGAO_DROPTARGET = 256,
SFGAO_CAPABILITYMASK = 375,
SFGAO_LINK = 65536,
SFGAO_SHARE = 131072,
SFGAO_READONLY = 262144,
SFGAO_GHOSTED = 524288,
SFGAO_DISPLAYATTRMASK = 983040,
SFGAO_FILESYSANCESTOR = 268435456,
SFGAO_FOLDER = 536870912,
SFGAO_FILESYSTEM = 1073741824,
SFGAO_HASSUBFOLDER = -2147483648,
SFGAO_CONTENTSMASK = -2147483648,
SFGAO_VALIDATE = 16777216,
SFGAO_REMOVABLE = 33554432,
SFGAO_COMPRESSED = 67108864,
}
private enum EIEIFLAG
{
IEIFLAG_ASYNC = 1,
IEIFLAG_CACHE = 2,
IEIFLAG_ASPECT = 4,
IEIFLAG_OFFLINE = 8,
IEIFLAG_GLEAM = 16,
IEIFLAG_SCREEN = 32,
IEIFLAG_ORIGSIZE = 64,
IEIFLAG_NOSTAMP = 128,
IEIFLAG_NOBORDER = 256,
IEIFLAG_QUALITY = 512
}
[StructLayout(LayoutKind.Sequential, Pack = 4, Size = 0, CharSet = CharSet.Auto)]
private struct STRRET_CSTR
{
public ESTRRET uType;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 520)]
public byte[] cStr;
}
[StructLayout(LayoutKind.Explicit, CharSet = CharSet.Auto)]
private struct STRRET_ANY
{
[FieldOffset(0)]
public ESTRRET uType;
[FieldOffset(4)]
public IntPtr pOLEString;
}
[StructLayoutAttribute(LayoutKind.Sequential)]
private struct SIZE
{
public int cx;
public int cy;
}
[ComImport(), Guid("00000000-0000-0000-C000-000000000046")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
private interface IUnknown
{
[PreserveSig()]
IntPtr QueryInterface(ref Guid riid, ref IntPtr pVoid);
[PreserveSig()]
IntPtr AddRef();
[PreserveSig()]
IntPtr Release();
}
[ComImportAttribute()]
[GuidAttribute("00000002-0000-0000-C000-000000000046")]
[InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
private interface IMalloc
{
[PreserveSig()]
IntPtr Alloc(int cb);
[PreserveSig()]
IntPtr Realloc(IntPtr pv, int cb);
[PreserveSig()]
void Free(IntPtr pv);
[PreserveSig()]
int GetSize(IntPtr pv);
[PreserveSig()]
int DidAlloc(IntPtr pv);
[PreserveSig()]
void HeapMinimize();
}
[ComImportAttribute()]
[GuidAttribute("000214F2-0000-0000-C000-000000000046")]
[InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
private interface IEnumIDList
{
[PreserveSig()]
int Next(int celt, ref IntPtr rgelt, ref int pceltFetched);
void Skip(int celt);
void Reset();
void Clone(ref IEnumIDList ppenum);
}
[ComImportAttribute()]
[GuidAttribute("000214E6-0000-0000-C000-000000000046")]
[InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
private interface IShellFolder
{
void ParseDisplayName(IntPtr hwndOwner, IntPtr pbcReserved,
[MarshalAs(UnmanagedType.LPWStr)]string lpszDisplayName,
ref int pchEaten, ref IntPtr ppidl, ref int pdwAttributes);
void EnumObjects(IntPtr hwndOwner,
[MarshalAs(UnmanagedType.U4)]ESHCONTF grfFlags,
ref IEnumIDList ppenumIDList);
void BindToObject(IntPtr pidl, IntPtr pbcReserved, ref Guid riid,
ref IShellFolder ppvOut);
void BindToStorage(IntPtr pidl, IntPtr pbcReserved, ref Guid riid, IntPtr ppvObj);
[PreserveSig()]
int CompareIDs(IntPtr lParam, IntPtr pidl1, IntPtr pidl2);
void CreateViewObject(IntPtr hwndOwner, ref Guid riid,
IntPtr ppvOut);
void GetAttributesOf(int cidl, IntPtr apidl,
[MarshalAs(UnmanagedType.U4)]ref ESFGAO rgfInOut);
void GetUIObjectOf(IntPtr hwndOwner, int cidl, ref IntPtr apidl, ref Guid riid, ref int prgfInOut, ref IUnknown ppvOut);
void GetDisplayNameOf(IntPtr pidl,
[MarshalAs(UnmanagedType.U4)]ESHGDN uFlags,
ref STRRET_CSTR lpName);
void SetNameOf(IntPtr hwndOwner, IntPtr pidl,
[MarshalAs(UnmanagedType.LPWStr)]string lpszName,
[MarshalAs(UnmanagedType.U4)] ESHCONTF uFlags,
ref IntPtr ppidlOut);
}
[ComImportAttribute(), GuidAttribute("BB2E617C-0920-11d1-9A0B-00C04FC2D6C1"), InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
private interface IExtractImage
{
void GetLocation([Out(), MarshalAs(UnmanagedType.LPWStr)]
StringBuilder pszPathBuffer, int cch, ref int pdwPriority, ref SIZE prgSize, int dwRecClrDepth, ref int pdwFlags);
void Extract(ref IntPtr phBmpThumbnail);
}
private class UnmanagedMethods
{
[DllImport("shell32", CharSet = CharSet.Auto)]
internal extern static int SHGetMalloc(ref IMalloc ppMalloc);
[DllImport("shell32", CharSet = CharSet.Auto)]
internal extern static int SHGetDesktopFolder(ref IShellFolder ppshf);
[DllImport("shell32", CharSet = CharSet.Auto)]
internal extern static int SHGetPathFromIDList(IntPtr pidl, StringBuilder pszPath);
[DllImport("gdi32", CharSet = CharSet.Auto)]
internal extern static int DeleteObject(IntPtr hObject);
}
~ShellThumbnail()
{
Dispose();
}
private IMalloc alloc = null;
private bool disposed = false;
private Size _desiredSize = new Size(100, 100);
private Bitmap _thumbNail;
public Bitmap ThumbNail
{
get
{
return _thumbNail;
}
}
public Size DesiredSize
{
get { return _desiredSize; }
set { _desiredSize = value; }
}
private IMalloc Allocator
{
get
{
if (!disposed)
{
if (alloc == null)
{
UnmanagedMethods.SHGetMalloc(ref alloc);
}
}
else
{
Debug.Assert(false, "Object has been disposed.");
}
return alloc;
}
}
public Bitmap GetThumbnail(string fileName)
{
if (string.IsNullOrEmpty(fileName))
return null;
if (!File.Exists(fileName) && !Directory.Exists(fileName))
{
throw new FileNotFoundException(string.Format("The file '{0}' does not exist", fileName), fileName);
}
if (_thumbNail != null)
{
_thumbNail.Dispose();
_thumbNail = null;
}
IShellFolder folder = null;
try
{
folder = getDesktopFolder;
}
catch (Exception ex)
{
throw ex;
}
if (folder != null)
{
IntPtr pidlMain = IntPtr.Zero;
try
{
int cParsed = 0;
int pdwAttrib = 0;
string filePath = Path.GetDirectoryName(fileName);
folder.ParseDisplayName(IntPtr.Zero, IntPtr.Zero, filePath, ref cParsed, ref pidlMain, ref pdwAttrib);
}
catch (Exception ex)
{
Marshal.ReleaseComObject(folder);
throw ex;
}
if (pidlMain != IntPtr.Zero)
{
Guid iidShellFolder = new Guid("000214E6-0000-0000-C000-000000000046");
IShellFolder item = null;
try
{
folder.BindToObject(pidlMain, IntPtr.Zero, ref iidShellFolder, ref item);
}
catch (Exception ex)
{
Marshal.ReleaseComObject(folder);
Allocator.Free(pidlMain);
throw ex;
}
if (item != null)
{
IEnumIDList idEnum = null;
try
{
item.EnumObjects(IntPtr.Zero, (ESHCONTF.SHCONTF_FOLDERS | ESHCONTF.SHCONTF_NONFOLDERS), ref idEnum);
}
catch (Exception ex)
{
Marshal.ReleaseComObject(folder);
Allocator.Free(pidlMain);
throw ex;
}
if (idEnum != null)
{
int hRes = 0;
IntPtr pidl = IntPtr.Zero;
int fetched = 0;
bool complete = false;
while (!complete)
{
hRes = idEnum.Next(1, ref pidl, ref fetched);
if (hRes != 0)
{
pidl = IntPtr.Zero;
complete = true;
}
else
{
if (_getThumbNail(fileName, pidl, item))
{
complete = true;
}
}
if (pidl != IntPtr.Zero)
{
Allocator.Free(pidl);
}
}
Marshal.ReleaseComObject(idEnum);
}
Marshal.ReleaseComObject(item);
}
Allocator.Free(pidlMain);
}
Marshal.ReleaseComObject(folder);
}
return ThumbNail;
}
private bool _getThumbNail(string file, IntPtr pidl, IShellFolder item)
{
IntPtr hBmp = IntPtr.Zero;
IExtractImage extractImage = null;
try
{
string pidlPath = PathFromPidl(pidl);
if (Path.GetFileName(pidlPath).ToUpper().Equals(Path.GetFileName(file).ToUpper()))
{
IUnknown iunk = null;
int prgf = 0;
Guid iidExtractImage = new Guid("BB2E617C-0920-11d1-9A0B-00C04FC2D6C1");
item.GetUIObjectOf(IntPtr.Zero, 1, ref pidl, ref iidExtractImage, ref prgf, ref iunk);
extractImage = (IExtractImage)iunk;
if (extractImage != null)
{
Console.WriteLine("Got an IExtractImage object!");
SIZE sz = new SIZE();
sz.cx = DesiredSize.Width;
sz.cy = DesiredSize.Height;
StringBuilder location = new StringBuilder(260, 260);
int priority = 0;
int requestedColourDepth = 32;
EIEIFLAG flags = EIEIFLAG.IEIFLAG_ASPECT | EIEIFLAG.IEIFLAG_SCREEN;
int uFlags = (int)flags;
try
{
extractImage.GetLocation(location, location.Capacity, ref priority, ref sz, requestedColourDepth, ref uFlags);
extractImage.Extract(ref hBmp);
}
catch (System.Runtime.InteropServices.COMException ex)
{
}
if (hBmp != IntPtr.Zero)
{
_thumbNail = Bitmap.FromHbitmap(hBmp);
}
Marshal.ReleaseComObject(extractImage);
extractImage = null;
}
return true;
}
else
{
return false;
}
}
catch (Exception ex)
{
if (hBmp != IntPtr.Zero)
{
UnmanagedMethods.DeleteObject(hBmp);
}
if (extractImage != null)
{
Marshal.ReleaseComObject(extractImage);
}
throw ex;
}
}
private string PathFromPidl(IntPtr pidl)
{
StringBuilder path = new StringBuilder(260, 260);
int result = UnmanagedMethods.SHGetPathFromIDList(pidl, path);
if (result == 0)
{
return string.Empty;
}
else
{
return path.ToString();
}
}
private IShellFolder getDesktopFolder
{
get
{
IShellFolder ppshf = null;
int r = UnmanagedMethods.SHGetDesktopFolder(ref ppshf);
return ppshf;
}
}
public void Dispose()
{
if (!disposed)
{
if (alloc != null)
{
Marshal.ReleaseComObject(alloc);
}
alloc = null;
if (_thumbNail != null)
{
_thumbNail.Dispose();
}
disposed = true;
}
}
}
}
答案 4 :(得分:1)
不幸的是,XP / 2003不支持Windows API代码包缩略图调用。
答案 5 :(得分:0)
不完全是您的要求,但是here's a project to open a Thumbs.db file The Wikipedia article has more information如何在Vista中找到缩略图&amp; 7。
以下是获取图片的代码:
public byte[] GetThumbData(string filename)
{
IStorageWrapper wrapper = new IStorageWrapper(_thumbDBFile, false);
foreach(CatalogItem catItem in _catalogItems)
{
if (catItem.filename == filename)
{
string streamName = BuildReverseString(catItem.itemID);
FileObject fileObject = wrapper.OpenUCOMStream(null, streamName);
byte[] rawJPGData = new byte [fileObject.Length];
fileObject.Read(rawJPGData, 0, (int)fileObject.Length);
fileObject.Close();
// 3 ints of header data need to be removed
// Don't know what first int is.
// 2nd int is thumb index
// 3rd is size of thumbnail data.
byte[] jpgData = new byte[rawJPGData.Length - 12];
for (int index = 12; index < jpgData.Length; index++)
{
jpgData[index - 12] = rawJPGData[index];
}
return jpgData;
}
}
return null;
}
public Image GetThumbnailImage(string filename)
{
byte[] thumbData = GetThumbData(filename);
if (null == thumbData)
{
return null;
}
MemoryStream ms = new MemoryStream(thumbData);
Image img = Image.FromStream(ms);
return img;
}
答案 6 :(得分:0)
感谢@Christian Nunciato,我想解释更多:
在Nuget控制台中通过键入以下命令安装# A tibble: 6 x 2
Year Value
<chr> <dbl>
1 2002 0.0109
2 2001 -0.0273
3 2000 0.0113
4 1999 0.0148
5 1998 0.00841
6 1997 0.0361
ggplot(df, aes(x = Year, y = Value)) +
geom_col(aes(fill = Value)) +
scale_fill_gradient2_tableau()
后:
WindowsAPICodePack-Shell
首先,您应该知道this很酷的解决方案需要您在服务器上安装相关程序,例如,如果您希望外壳程序为PDF文件生成缩略图,则应该在服务器上安装 Acrobat Reader 或 Foxit PhantomPDF 之类的PDF阅读器或类似的东西,这意味着服务器将为其识别的文件创建缩略图,这很有意义
其次,检查以了解生成哪个文件扩展名的缩略图,换句话说,检查.psd或.msi文件扩展名是否具有正确的缩略图,然后阻止请求服务器生成缩略图给他们(在客户端和服务器端都检查)。
第三次,您可能需要通过Ajax获取缩略图,我个人建议您在第一秒根据文件类型为文件提供一些默认的缩略图,然后请求服务器生成缩略图。情况下,您可以使用以下代码片段(我将生成的Base64格式的位图作为图像接收,实际上是字符串):
服务器端代码:
Install-Package WindowsAPICodePack-Shell -Version 1.1.1
客户端代码:
[WebMethod]
public static string GetThumbnail(string path) {
string thumb = string.Empty;
path = @"D:\\" + path.Replace("/", "\\"); //Or Server.MapPath("/UploadedFiles");
if (File.Exists(path))
{
try
{
Microsoft.WindowsAPICodePack.Shell.ShellFile shellFile = Microsoft.WindowsAPICodePack.Shell.ShellFile.FromFilePath(path);
System.Drawing.Bitmap shellThumb = shellFile.Thumbnail.ExtraLargeBitmap;
MemoryStream ms = new MemoryStream();
shellThumb.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);//Jpeg is preferred, Png would make a bigger file size
thumb = Convert.ToBase64String(ms.ToArray());
}
catch(Exception ex)
{
}
}
return thumb;
}
请注意,由于返回的字符串可能是一个长文本,因此您可能会遇到以下错误提示:
var url = "Default.aspx/GetThumbnail",
path = "Images/1.jpg",//For instance
extension = path.split(".").pop().toLowerCase(),
allowedExtensions = ["jpg", "jpeg", "png", "gif", "pdf", "mp4"];
if (allowedExtensions.includes(extension)){
$.ajax({
type: 'POST',
contentType: "application/json; charset=utf-8",
url: url,
data: "{'path':'" + path + "'}",
async: true,
xhrFields: {
withCredentials: true
},
success: function (response) {
if (!$.isEmptyObject(response.d))
$(elem).find("img").attr("src", "data:image/jpg;base64," + response.d);
},
error: function (err) {
console.error(err);
}
});
}
在这种情况下,您必须在web.config文件中添加以下代码:
Error during serialization or deserialization using the JSON JavaScriptSerializer. The length of the string exceeds the value set on the maxJsonLength property base64
maxJsonLength是一个整数值,可以是Int32.MaxValue,您可以阅读更多here。
答案 7 :(得分:-2)
您应该使用Windows GDI +来获取这些缩略图,例如this。