當前位置:
首頁 > 知識 > C 語言獲取任意文件的縮略圖

C 語言獲取任意文件的縮略圖

因為用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 語言獲取任意文件的縮略圖

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 程序員小新人學習 的精彩文章:

SparkStreaming如何解決小文件問題
利用fastjson反序列化json為對象和對象數組

TAG:程序員小新人學習 |