因为用shell取缩略图时,对于损坏的文件,读出来的图有黑边,所以就诞生了以下方法,不过这个效率要比用shell取的低3-4倍(耗时主要是在将黑色背景转为透明的过程)。

1.添加类WindowsThumbnailProvider

[csharp] view plain copy

  1. [Flags]
  2. public enum ThumbnailOptions
  3. {
  4. None = 0x00,
  5. BiggerSizeOk = 0x01,
  6. InMemoryOnly = 0x02,
  7. IconOnly = 0x04,
  8. ThumbnailOnly = 0x08,
  9. InCacheOnly = 0x10,
  10. }
  11. public class WindowsThumbnailProvider
  12. {
  13. private const string IShellItem2Guid = "7E9FB0D3-919F-4307-AB2E-9B1860310C93";
  14. [dllImport("shell32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
  15. internal static extern int SHCreateItemFromParsingName(
  16. [MarshalAs(UnmanagedType.LPWStr)] string path,
  17. // The following parameter is not used - binding context.
  18. IntPtr pbc,
  19. ref Guid riid,
  20. [MarshalAs(UnmanagedType.Interface)] out IShellItem shellItem);
  21. [DllImport("gdi32.dll")]
  22. [return: MarshalAs(UnmanagedType.Bool)]
  23. internal static extern bool DeleteObject(IntPtr hObject);
  24. [ComImport]
  25. [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
  26. [Guid("43826d1e-e718-42ee-bc55-a1e261c37bfe")]
  27. internal interface IShellItem
  28. {
  29. void BindToHandler(IntPtr pbc,
  30. [MarshalAs(UnmanagedType.LPStruct)]Guid bhid,
  31. [MarshalAs(UnmanagedType.LPStruct)]Guid riid,
  32. out IntPtr ppv);
  33. void GetParent(out IShellItem ppsi);
  34. void GetDisplayName(SIGDN sigdnName, out IntPtr ppszName);
  35. void GetAttributes(uint sfgaoMask, out uint psfgaoAttribs);
  36. void Compare(IShellItem psi, uint hint, out int piOrder);
  37. };
  38. internal enum SIGDN : uint
  39. {
  40. NORMALDISPLAY = 0,
  41. PARENTRELATIVEPARSING = 0x80018001,
  42. PARENTRELATIVEFORADDRESSBAR = 0x8001c001,
  43. DESKTOPABSOLUTEPARSING = 0x80028000,
  44. PARENTRELATIVEEDITING = 0x80031001,
  45. DESKTOPABSOLUTEEDITING = 0x8004c000,
  46. FILESYSPATH = 0x80058000,
  47. URL = 0x80068000
  48. }
  49. internal enum HResult
  50. {
  51. Ok = 0x0000,
  52. False = 0x0001,
  53. InvalidArguments = unchecked((int)0x80070057),
  54. OutOfMemory = unchecked((int)0x8007000E),
  55. NoInterface = unchecked((int)0x80004002),
  56. Fail = unchecked((int)0x80004005),
  57. ElementNotFound = unchecked((int)0x80070490),
  58. TypeElementNotFound = unchecked((int)0x8002802B),
  59. NoObject = unchecked((int)0x800401E5),
  60. Win32ErrorCanceled = 1223,
  61. Canceled = unchecked((int)0x800704C7),
  62. ResourceInUse = unchecked((int)0x800700AA),
  63. AccessDenied = unchecked((int)0x80030005)
  64. }
  65. [ComImportAttribute()]
  66. [GuidAttribute("bcc18b79-ba16-442f-80c4-8a59c30c463b")]
  67. [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
  68. internal interface IShellItemImageFactory
  69. {
  70. [PreserveSig]
  71. HResult GetImage(
  72. [In, MarshalAs(UnmanagedType.Struct)] NativeSize size,
  73. [In] ThumbnailOptions flags,
  74. [Out] out IntPtr phbm);
  75. }
  76. [StructLayout(LayoutKind.Sequential)]
  77. internal struct NativeSize
  78. {
  79. private int width;
  80. private int height;
  81. public int Width { set { width = value; } }
  82. public int Height { set { height = value; } }
  83. };
  84. [StructLayout(LayoutKind.Sequential)]
  85. public struct RGBQUAD
  86. {
  87. public byte rgbBlue;
  88. public byte rgbGreen;
  89. public byte rgbRed;
  90. public byte rgbReserved;
  91. }
  92. public static Bitmap GetThumbnail(string fileName, int width, int height, ThumbnailOptions options)
  93. {
  94. IntPtr hBitmap = GetHBitmap(Path.GetFullPath(fileName), width, height, options);
  95. try
  96. {
  97. // return a System.Drawing.Bitmap from the hBitmap
  98. return GetBitmapFromHBitmap(hBitmap);
  99. }
  100. finally
  101. {
  102. // delete HBitmap to avoid memory leaks
  103. DeleteObject(hBitmap);
  104. }
  105. }
  106. public static Bitmap GetBitmapFromHBitmap(IntPtr nativeHBitmap)
  107. {
  108. Bitmap bmp = Bitmap.FromHbitmap(nativeHBitmap);
  109. if (Bitmap.GetPixelFormatSize(bmp.PixelFormat) < 32)
  110. return bmp;
  111. return CreateAlphaBitmap(bmp, PixelFormat.Format32bppArgb);
  112. }
  113. public static Bitmap CreateAlphaBitmap(Bitmap srcBitmap, PixelFormat targetPixelFormat)
  114. {
  115. Bitmap result = new Bitmap(srcBitmap.Width, srcBitmap.Height, targetPixelFormat);
  116. Rectangle bmpBounds = new Rectangle(0, 0, srcBitmap.Width, srcBitmap.Height);
  117. BitmapData srcData = srcBitmap.LockBits(bmpBounds, ImageLockMode.ReadOnly, srcBitmap.PixelFormat);
  118. bool isAlplaBitmap = false;
  119. try
  120. {
  121. for (int y = 0; y <= srcData.Height - 1; y )
  122. {
  123. for (int x = 0; x <= srcData.Width - 1; x )
  124. {
  125. Color pixelColor = Color.FromArgb(
  126. Marshal.ReadInt32(srcData.Scan0, (srcData.Stride * y) (4 * x)));
  127. if (pixelColor.A > 0 & pixelColor.A < 255)
  128. {
  129. isAlplaBitmap = true;
  130. }
  131. result.SetPixel(x, y, pixelColor);
  132. }
  133. }
  134. }
  135. finally
  136. {
  137. srcBitmap.UnlockBits(srcData);
  138. }
  139. if (isAlplaBitmap)
  140. {
  141. return result;
  142. }
  143. else
  144. {
  145. return srcBitmap;
  146. }
  147. }
  148. private static IntPtr GetHBitmap(string fileName, int width, int height, ThumbnailOptions options)
  149. {
  150. IShellItem nativeShellItem;
  151. Guid shellItem2Guid = new Guid(IShellItem2Guid);
  152. int retCode = SHCreateItemFromParsingName(fileName, IntPtr.Zero, ref shellItem2Guid, out nativeShellItem);
  153. if (retCode != 0)
  154. throw Marshal.GetExceptionForHR(retCode);
  155. NativeSize nativeSize = new NativeSize();
  156. nativeSize.Width = width;
  157. nativeSize.Height = height;
  158. IntPtr hBitmap;
  159. HResult hr = ((IShellItemImageFactory)nativeShellItem).GetImage(nativeSize, options, out hBitmap);
  160. Marshal.ReleaseComObject(nativeShellItem);
  161. if (hr == HResult.Ok) return hBitmap;
  162. throw Marshal.GetExceptionForHR((int)hr);
  163. }
  164. }

2.使用方法:[csharp] view plain copy

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

c语言获得当前文件指针位置(语言获取任意文件的缩略图)(1)

,