6

I’m using WindowsAPICodePack, getting ShellFile’s Thumbnail’s. But some of those which look like the generic icons – have a black background. I therefore make it a Bitmap and set Black as transparent.

The problem is that when it’s a thumbnail of a picture – it shouldn’t do it. How can I tell a real thumbnail from an “icon”?

My code:

ShellFile sf = ShellFile.FromFilePath(path);
Bitmap bm = sf.Thumbnail.MediumBitmap;
bm.MakeTransparent(Color.Black);

Thanks

ispiro
  • 26,556
  • 38
  • 136
  • 291
  • 2
    Hard to see how MakeTransparent can work well on icons that contain black. Anyhoo, use the FormatOption property to first ask for only an icon. If that fails, ask for a thumbnail. – Hans Passant Oct 02 '11 at 13:11
  • @Hans a) Thanks. Exactly what I was looking for. (but first I ask for a thumbnail - there’s always an icon). b) Is there another way to get rid of the background color? If not – I guess I can always get an icon instead of a bitmap, now that I know it’s not going to be a thumbnail. – ispiro Oct 02 '11 at 14:21

1 Answers1

5

You can approach this problem from another angle. It is possible to force the ShellFile.Thumbnail to only extract the thumbnail picture if it exists or to force it to extract the associated application icon.

So your code would look something like this:

Bitmap bm;
using (ShellFile shellFile = ShellFile.FromFilePath(filePath))
{
    ShellThumbnail thumbnail = shellFile.Thumbnail;

    thumbnail.FormatOption = ShellThumbnailFormatOption.ThumbnailOnly;

    try
    {
        bm = thumbnail.MediumBitmap;
    }
    catch // errors can occur with windows api calls so just skip
    {
        bm = null;
    }
    if (bm == null)
    {
        thumbnail.FormatOption = ShellThumbnailFormatOption.IconOnly;
        bm = thumbnail.MediumBitmap;
        // make icon transparent
        bm.MakeTransparent(Color.Black);
    }
}
Kev
  • 1,832
  • 1
  • 19
  • 24
  • 1
    "errors can occur with windows api calls so just skip" - is this good practice? – BudBrot Jul 10 '14 at 14:29
  • You can catch only a COMException with HResult 0x8004B200 like this: `catch (InvalidOperationException ex) { COMException comException = ex.GetBaseException() as COMException; if (comException.ErrorCode != unchecked((int)0x8004B200)) throw; // TODO: Do something }` – Roman Štefko Dec 19 '17 at 13:36