4

Is there any way to determine if WPF will be able to load an image file without attempting to construct a BitmapImage and catching the exception if it fails?

I'm creating an image browser that attempts to show previews of all the images on a removable drive. There could be a lot of files that aren't images and catching an exception for each one seems somewhat inefficient but I can't think of a way that isn't prone to error.

Any suggestions?

Thanks, Mark

MarkDaniel
  • 147
  • 2
  • 10
  • No, sniffing the file is much too involved. Catch the exception. – Hans Passant Dec 01 '11 at 14:07
  • You will be scanning common image extension only, won't you? – Gert Arnold Dec 01 '11 at 14:20
  • 1
    I would use extension and / or mime type to include or exclude. In the end you still need a try catch. If you want to error on the side of trying then only exclude what you consider bad extensions and / or mime types. This is post on how to sniff the mime type http://stackoverflow.com/questions/58510/using-net-how-can-you-find-the-mime-type-of-a-file-based-on-the-file-signature – paparazzo Dec 01 '11 at 14:58
  • Does this answer your question? [Get supported image formats from BitmapImage](https://stackoverflow.com/questions/36390013/get-supported-image-formats-from-bitmapimage) – StayOnTarget Jun 04 '21 at 14:06
  • This question is a dupe of https://stackoverflow.com/questions/36390013/get-supported-image-formats-from-bitmapimage ... the accepted answer here even just links to that one. – StayOnTarget Jun 04 '21 at 14:07

4 Answers4

3

I recently asked a very similar question and got an excellent answer here.

Basically, you find all the codecs on a user's machine which BitmapImage can use to open various image formats. From these codecs, you build a list of the file extensions that these can open.

Then, when your program tries to open a file, check the extension of that file against this list.

WPF uses WIC to handle images. It contains a core set of codecs that handle common image formats, and I believe you can hard-code the extensions of these from here. WIC is also extensible, so, for example, camera manufacturers can incorporate custom image formats into WIC. The code in the answer above searches your computer for these extra codecs, and provides the corresponding file extensions for these.

This method assumes that the file extensions are correct for a file. This is usually a fair assumption in most cases though - even Windows Explorer is happy to assume this. Still, I would wrap the BitmapImage construction in a try-catch, should the odd rogue file appear where the extension appears to be an image, but it still won't open.

EDIT: I have also wrapped this functionality into a class you can copy-paste into your own project here.

Community
  • 1
  • 1
James R
  • 156
  • 1
  • 11
1

WPF uses WIC, what you want is demonstrated in C++ in the MSDN but the decompiled sources of the framework show that IWICImagingFactory::CreateComponentEnumerator isn't even exposed in the internal class of the framework.

Your best solution would be to create a static list of extensions supported (The formats that WIC support out-of-the box are on MSDN) and use it.

Julien Roncaglia
  • 17,397
  • 4
  • 57
  • 75
0

First, you can try to check the image file extension to verify if your application is able to read it.

Then you have to read Validate image from file in C#

and here Getting image dimensions without reading the entire file

Community
  • 1
  • 1
NoWar
  • 36,338
  • 80
  • 323
  • 498
  • 1
    The problem is that users can, in principle, install their own codecs (see http://msdn.microsoft.com/en-us/library/ms748873.aspx#_metadata) and I can't see any way of finding the available codecs let alone the file extensions that pertain to the those codecs. Also the extension might be wrong or missing. – MarkDaniel Dec 01 '11 at 15:34
-1

I found the answer to this in another question on StackOverflow, but I don't remember the question I got it from. In any event, here's some code I wrote based on what one of the answerws to that question said:

public static string GetImageFileExtension( byte[] plateImage ) {
    string imageFileExtension = String.Empty;
    using ( Stream ms = new MemoryStream( plateImage ) ) {
        BitmapDecoder decoder = BitmapDecoder.Create( ms, BitmapCreateOptions.None, BitmapCacheOption.None );
             if ( decoder is BmpBitmapDecoder  ) imageFileExtension = ".bmp";
        else if ( decoder is GifBitmapDecoder  ) imageFileExtension = ".gif";
        else if ( decoder is IconBitmapDecoder ) imageFileExtension = ".ico";
        else if ( decoder is JpegBitmapDecoder ) imageFileExtension = ".jpg";
        else if ( decoder is PngBitmapDecoder  ) imageFileExtension = ".png";
        else if ( decoder is TiffBitmapDecoder ) imageFileExtension = ".tiff";
        else if ( decoder is WmpBitmapDecoder  ) imageFileExtension = ".wmp";
    }
    return imageFileExtension;
}

This works well in production code.

Tony Vitabile
  • 8,298
  • 15
  • 67
  • 123
  • But what happens if the file turns out not to be an image? I think BitmapDecoder.Create will throw an Exception which is what I was trying to avoid. – MarkDaniel Jan 30 '13 at 10:57
  • In my application, the `byte` array will always contain a bitmap of some kind, so I don't have that problem. In that case, the only other way around handling the exception is to write your own class that parses the bitmap header. Which I'm guessing you've already done? – Tony Vitabile Jan 30 '13 at 21:10
  • A check of the documentation for the BitmapDecoder.Create method shows that no exceptions are listed. I don't know what the function does if the data in the `Stream` is not an image in that case. – Tony Vitabile Jan 30 '13 at 21:13