开发者

Extracting thumbnail and icon from file in c#

I'm trying to extract thumbnail or icon if the thumbnail is not available from a file or folder like windows explorer. I'm using IShellItemImageFactory and when the thumbnail is present it works nicely. However, if the file does not have a thumbnail the icon returned by the method has a black backgro开发者_运维百科und.

Is suspect the reason for this is that the transparency is lost when I call Bitmap.FromHbitmap to convert the hbitmap to bitmap. Is it possible to convert without losing the transparency? I'm not even sure if that's the problem or not. The only reference that I could find is a comment to question about IShellItemImageFactory which says that

"the API sometimes returns bitmaps that use pre-multiplied alpha and sometimes ones that use normal alpha"

Is there any way to get the icon without black background or should I just stick to Icon.ExtractAssociatedIcon when there is no thumbnail?


I use the following code, not sure if it transparent backgrounds are supported but you could give it a 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);


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

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜