Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get supported image formats from BitmapImage

How can I get a list of image formats supported by System.Windows.Media.Imaging.BitmapImage?

I am writing a simple image processing tool in C# WPF. The BitmapImage class is one of the more useful bitmap classes as it is able to decode from a wide variety of formats.

In particular, it is able to open NEF (Nikon's RAW format) on my computer. It is likely that BitmapImage can open a wide variety of RAW formats from other manufacturers, a function I am keen to make use of.

As I don't know every format that can be opened as a BitmapImage, I am currently using a try/catch to try and construct a BitmapImage from every file that the user tries to open. This is clearly not the most efficient way.

As far as I know, BitmapImage inherits from BitmapSource, which decides which files it can open by looking on the user's system for available codecs. It's likely therefore that codec availability varies between machines, meaning a list of supported formats can't be hard-coded into the program. I need a way to check what these supported formats on a user's machine are.

I found this method in System.Drawing. This returns a list of supported codecs with a list of supported file extensions, and an equivalent for Systems.Windows.Media.Imaging would be exactly what I need.

like image 784
James R Avatar asked Apr 03 '16 19:04

James R


People also ask

Which extension is used for standard bitmapped format for storing graphics?

The BMP file format, also known as bitmap image file, device independent bitmap (DIB) file format and bitmap, is a raster graphics image file format used to store bitmap digital images, independently of the display device (such as a graphics adapter), especially on Microsoft Windows and OS/2 operating systems.

What is bitmap image in C#?

A bitmap consists of the pixel data for a graphics image and its attributes. There are many standard formats for saving a bitmap to a file. GDI+ supports the following file formats: BMP, GIF, EXIF, JPG, PNG, and TIFF. For more information about supported formats, see Types of Bitmaps.

Which of these formats is not a bitmap image?

The correct answer is ODT. A bitmap basically describes a type of image. Pixels all the basic sources of information. BMP, GIF, JPEG, EXIF, PNG, and TIFF are bitmap file formats.


1 Answers

If you do not want to deal with WIC directly as shown in the source code linked to in the answer mentioned by Clemens, you can read a list of additional codecs (those that are not supported by WIC by default) with their names and supported file extensions directly from the registry.

See the following sample code.

/// <summary>
/// Sample code: Show the additional registered decoders 
/// </summary>
private void Button_Click(object sender, RoutedEventArgs e)
{
    var additionalDecoders = GetAdditionalDecoders();

    foreach(var additionalDecoder in additionalDecoders)
    {
        MessageBox.Show(additionalDecoder.FriendlyName + ":" + additionalDecoder.FileExtensions);
    }
}

/// <summary>
/// GUID of the component registration group for WIC decoders
/// </summary>
private const string WICDecoderCategory = "{7ED96837-96F0-4812-B211-F13C24117ED3}";

/// <summary>
/// Represents information about a WIC decoder
/// </summary>
public struct DecoderInfo
{
    public string FriendlyName;
    public string FileExtensions;
}

/// <summary>
/// Gets a list of additionally registered WIC decoders
/// </summary>
/// <returns></returns>
public static IEnumerable<DecoderInfo> GetAdditionalDecoders()
{
    var result = new List<DecoderInfo>();

    string baseKeyPath;
    
    // If we are a 32 bit process running on a 64 bit operating system, 
    // we find our config in Wow6432Node subkey
    if (Environment.Is64BitOperatingSystem && !Environment.Is64BitProcess)
    {
        baseKeyPath = "Wow6432Node\\CLSID";
    }
    else
    {
        baseKeyPath = "CLSID";
    }
    
    RegistryKey baseKey = Registry.ClassesRoot.OpenSubKey(baseKeyPath, false);
    if (baseKey != null)
    {
        var categoryKey = baseKey.OpenSubKey(WICDecoderCategory + "\\instance", false);
        if (categoryKey != null)
        {
            // Read the guids of the registered decoders
            var codecGuids = categoryKey.GetSubKeyNames();

            foreach (var codecGuid in codecGuids)
            {
                // Read the properties of the single registered decoder
                var codecKey = baseKey.OpenSubKey(codecGuid);
                if (codecKey != null)
                {
                    DecoderInfo decoderInfo = new DecoderInfo();
                    decoderInfo.FriendlyName = Convert.ToString(codecKey.GetValue("FriendlyName", ""));
                    decoderInfo.FileExtensions = Convert.ToString(codecKey.GetValue("FileExtensions", ""));
                    result.Add(decoderInfo);
                }
            }
        }
    }
    
    return result;
}

Note that this can return different results depending on whether you are running in a 32 bit or 64 bit process. For example, on my Windows 10 machine I have a Photoshop decoder by Microsoft installed to read psd files. However, only a 32 bit version is installed.

So, when I try to load a Photoshop psd file via BitmapImage, this succeeds when running a 32 bit application but not when running a 64 bit application. The code above reading the installed decoders from the registry reflects this correctly.

like image 168
NineBerry Avatar answered Sep 21 '22 04:09

NineBerry