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.
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.
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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With