MarkDaniel
MarkDaniel

Reputation: 147

What is the best way to determine if WPF can load an image file?

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

Upvotes: 4

Views: 2974

Answers (4)

James R
James R

Reputation: 166

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.

Upvotes: 3

Tony Vitabile
Tony Vitabile

Reputation: 8594

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.

Upvotes: -1

NoWar
NoWar

Reputation: 37633

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

Upvotes: 0

Julien Roncaglia
Julien Roncaglia

Reputation: 17837

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.

Upvotes: 1

Related Questions