Extract thumbnail and icon from file in C #

I am trying to extract a thumbnail or icon if the thumbnail is not accessible from a file or folder such as Windows Explorer. I use IShellItemImageFactory, and when a thumbnail is present, it works beautifully. However, if the file does not have a thumbnail, the icon returned by the method has a black background.

Suspiciously, the reason is that transparency is lost when I call Bitmap.FromHbitmap to convert hbitmap to bitmap. Is it possible to convert without loss of transparency? I'm not even sure if this is a problem or not. The only link I could find was a comment on the IShellItemImageFactory question , which says that

"The API sometimes returns bitmaps that use pre-multiplied alpha and sometimes those that use normal alpha."

Is there a way to get an icon without a black background, or should I just stick with Icon.ExtractAssociatedIcon when there is no thumbnail?

+4
source share
2 answers

I use the following code, not sure if its transparent backgrounds are supported, but you can try:

 private const uint SHGFI_ICON = 0x100; private const uint SHGFI_LARGEICON = 0x0; private const uint SHGFI_SMALLICON = 0x1; private const uint SHGFI_DISPLAYNAME = 0x00000200; private const uint SHGFI_TYPENAME = 0x400; public static Icon GetSmallFileIcon(this FileInfo file) { if (file.Exists) { SHFILEINFO shFileInfo = new SHFILEINFO(); SHGetFileInfo(file.FullName, 0, ref shFileInfo, (uint)Marshal.SizeOf(shFileInfo), SHGFI_ICON | SHGFI_SMALLICON); return Icon.FromHandle(shFileInfo.hIcon); } else return SystemIcons.WinLogo; } public static Icon GetSmallFileIcon(string fileName) { return GetSmallFileIcon(new FileInfo(fileName)); } public static Icon GetLargeFileIcon(this FileInfo file) { if (file.Exists) { SHFILEINFO shFileInfo = new SHFILEINFO(); SHGetFileInfo(file.FullName, 0, ref shFileInfo, (uint)Marshal.SizeOf(shFileInfo), SHGFI_ICON | SHGFI_LARGEICON); return Icon.FromHandle(shFileInfo.hIcon); } else return SystemIcons.WinLogo; } public static Icon GetLargeFileIcon(string fileName) { return GetLargeFileIcon(new FileInfo(fileName)); } [StructLayout(LayoutKind.Sequential)] public struct SHFILEINFO { public SHFILEINFO(bool b) { hIcon = IntPtr.Zero; iIcon = IntPtr.Zero; dwAttributes = 0; szDisplayName = ""; szTypeName = ""; } public IntPtr hIcon; public IntPtr iIcon; public uint dwAttributes; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)] public string szDisplayName; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 80)] public string szTypeName; }; [DllImport("shell32.dll")] public static extern IntPtr SHGetFileInfo(string pszPath, uint dwFileAttributes, ref SHFILEINFO psfi, uint cbSizeFileInfo, uint uFlags); 
+3
source

The returned bitmap has alpha. These are 32 bits, and the last 8 bits are alpha. I'm not sure what will happen to this in your call to Bitmap.FromHbitmap, but you should probably know that even if the alpha is copied correctly (perhaps this is so), you will not be able to use it later. If you ignore alpha, you will see a black box.

+1
source

Source: https://habr.com/ru/post/1333052/


All Articles