您现在的位置是:首页 > 文章详情

【C#】获取任意文件的缩略图

日期:2018-05-25点击:482
原文: 【C#】获取任意文件的缩略图

因为用shell取缩略图时,对于损坏的文件,读出来的图有黑边,所以就诞生了以下方法,不过这个效率要比用shell取的低3-4倍。

1.添加类WindowsThumbnailProvider

[Flags] public enum ThumbnailOptions { None = 0x00, BiggerSizeOk = 0x01, InMemoryOnly = 0x02, IconOnly = 0x04, ThumbnailOnly = 0x08, InCacheOnly = 0x10, } public class WindowsThumbnailProvider { private const string IShellItem2Guid = "7E9FB0D3-919F-4307-AB2E-9B1860310C93"; [DllImport("shell32.dll", CharSet = CharSet.Unicode, SetLastError = true)] internal static extern int SHCreateItemFromParsingName( [MarshalAs(UnmanagedType.LPWStr)] string path, // The following parameter is not used - binding context. IntPtr pbc, ref Guid riid, [MarshalAs(UnmanagedType.Interface)] out IShellItem shellItem); [DllImport("gdi32.dll")] [return: MarshalAs(UnmanagedType.Bool)] internal static extern bool DeleteObject(IntPtr hObject); [ComImport] [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] [Guid("43826d1e-e718-42ee-bc55-a1e261c37bfe")] internal interface IShellItem { void BindToHandler(IntPtr pbc, [MarshalAs(UnmanagedType.LPStruct)]Guid bhid, [MarshalAs(UnmanagedType.LPStruct)]Guid riid, out IntPtr ppv); void GetParent(out IShellItem ppsi); void GetDisplayName(SIGDN sigdnName, out IntPtr ppszName); void GetAttributes(uint sfgaoMask, out uint psfgaoAttribs); void Compare(IShellItem psi, uint hint, out int piOrder); }; internal enum SIGDN : uint { NORMALDISPLAY = 0, PARENTRELATIVEPARSING = 0x80018001, PARENTRELATIVEFORADDRESSBAR = 0x8001c001, DESKTOPABSOLUTEPARSING = 0x80028000, PARENTRELATIVEEDITING = 0x80031001, DESKTOPABSOLUTEEDITING = 0x8004c000, FILESYSPATH = 0x80058000, URL = 0x80068000 } internal enum HResult { Ok = 0x0000, False = 0x0001, InvalidArguments = unchecked((int)0x80070057), OutOfMemory = unchecked((int)0x8007000E), NoInterface = unchecked((int)0x80004002), Fail = unchecked((int)0x80004005), ElementNotFound = unchecked((int)0x80070490), TypeElementNotFound = unchecked((int)0x8002802B), NoObject = unchecked((int)0x800401E5), Win32ErrorCanceled = 1223, Canceled = unchecked((int)0x800704C7), ResourceInUse = unchecked((int)0x800700AA), AccessDenied = unchecked((int)0x80030005) } [ComImportAttribute()] [GuidAttribute("bcc18b79-ba16-442f-80c4-8a59c30c463b")] [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)] internal interface IShellItemImageFactory { [PreserveSig] HResult GetImage( [In, MarshalAs(UnmanagedType.Struct)] NativeSize size, [In] ThumbnailOptions flags, [Out] out IntPtr phbm); } [StructLayout(LayoutKind.Sequential)] internal struct NativeSize { private int width; private int height; public int Width { set { width = value; } } public int Height { set { height = value; } } }; [StructLayout(LayoutKind.Sequential)] public struct RGBQUAD { public byte rgbBlue; public byte rgbGreen; public byte rgbRed; public byte rgbReserved; } public static Bitmap GetThumbnail(string fileName, int width, int height, ThumbnailOptions options) { IntPtr hBitmap = GetHBitmap(Path.GetFullPath(fileName), width, height, options); try { // return a System.Drawing.Bitmap from the hBitmap return GetBitmapFromHBitmap(hBitmap); } finally { // delete HBitmap to avoid memory leaks DeleteObject(hBitmap); } } public static Bitmap GetBitmapFromHBitmap(IntPtr nativeHBitmap) { Bitmap bmp = Bitmap.FromHbitmap(nativeHBitmap); if (Bitmap.GetPixelFormatSize(bmp.PixelFormat) < 32) return bmp; return CreateAlphaBitmap(bmp, PixelFormat.Format32bppArgb); } public static Bitmap CreateAlphaBitmap(Bitmap srcBitmap, PixelFormat targetPixelFormat) { Bitmap result = new Bitmap(srcBitmap.Width, srcBitmap.Height, targetPixelFormat); Rectangle bmpBounds = new Rectangle(0, 0, srcBitmap.Width, srcBitmap.Height); BitmapData srcData = srcBitmap.LockBits(bmpBounds, ImageLockMode.ReadOnly, srcBitmap.PixelFormat); bool isAlplaBitmap = false; try { for (int y = 0; y <= srcData.Height - 1; y++) { for (int x = 0; x <= srcData.Width - 1; x++) { Color pixelColor = Color.FromArgb( Marshal.ReadInt32(srcData.Scan0, (srcData.Stride * y) + (4 * x))); if (pixelColor.A > 0 & pixelColor.A < 255) { isAlplaBitmap = true; } result.SetPixel(x, y, pixelColor); } } } finally { srcBitmap.UnlockBits(srcData); } if (isAlplaBitmap) { return result; } else { return srcBitmap; } } private static IntPtr GetHBitmap(string fileName, int width, int height, ThumbnailOptions options) { IShellItem nativeShellItem; Guid shellItem2Guid = new Guid(IShellItem2Guid); int retCode = SHCreateItemFromParsingName(fileName, IntPtr.Zero, ref shellItem2Guid, out nativeShellItem); if (retCode != 0) throw Marshal.GetExceptionForHR(retCode); NativeSize nativeSize = new NativeSize(); nativeSize.Width = width; nativeSize.Height = height; IntPtr hBitmap; HResult hr = ((IShellItemImageFactory)nativeShellItem).GetImage(nativeSize, options, out hBitmap); Marshal.ReleaseComObject(nativeShellItem); if (hr == HResult.Ok) return hBitmap; throw Marshal.GetExceptionForHR((int)hr); } }

2.使用方法:

 int pic_size = 256; Bitmap bm = WindowsThumbnailProvider.GetThumbnail(path, pic_size, pic_size, ThumbnailOptions.None);


原文链接:https://yq.aliyun.com/articles/678523
关注公众号

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。

持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。

转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。

文章评论

共有0条评论来说两句吧...

文章二维码

扫描即可查看该文章

点击排行

推荐阅读

最新文章