dotnet / wpf

WPF is a .NET Core UI framework for building Windows desktop applications.
MIT License
7.08k stars 1.17k forks source link

[API Proposal]: Add API for enumerating installed codecs #7930

Open udaken opened 1 year ago

udaken commented 1 year ago

Background and motivation

If an Out-Box type WIC codec such as WebP or AVIF is installed, the System.Windows.Media.Imaging.BitmapDecoder.Create() method can be used to process the image. However, it is not possible to retrieve information such as the extension of the installed codec from the WPF application. As a result, the application cannot indicate to the user that these codecs are available, for example, in the OpenFileDialog.

Therefore, we require an API that can retrieve information about all installed codecs.

API Proposal

namespace System.Windows.Media.Imaging;

public abstract class BitmapCodecInfo {
    // wrapper for IWICImagingFactory::CreateComponentEnumerator(WICDecoder) 
+   public static IEnumerable<BitmapCodecInfo> GetInstalledDecoderInfos();

    // wrapper for IWICImagingFactory::CreateComponentEnumerator(WICEncoder) 
+   public static IEnumerable<BitmapCodecInfo> GetInstalledEncoderInfos();
}

API Usage

Console.WriteLine("You can decode the following formats");

foreach (BitmapCodecInfo codecInfo in BitmapCodecInfo.GetInstalledDecoderInfos())
{
    Console.WriteLine(codecInfo.FileExtensions);
}   

Alternative Designs

Provide classes derived from BitmapCodecInfo for Encoder and Decoder.

namespace System.Windows.Media.Imaging;

+public class BitmapDecoderInfo : BitmapCodecInfo {
+   public static IEnumerable<BitmapDecoderInfo> GetInstalledDecoders();
+   public BitmapDecoder CreateDecoder();
+}
+public class BitmapEncoderInfo : BitmapCodecInfo {
+   public static IEnumerable<BitmapEncoderInfo> GetInstalledEncoders();
+   public BitmapEncoder CreateEncoder();
+}

Risks

No response

miloush commented 1 year ago

While I recognize the need and very much support the ability to enumerate decoders and encoders, I think the API could be a bit better. First it is a non-trivial operation so perhaps it should not be a property but a method. This would also allow you to control the enumeration options in the future. Then it is a bit unfortunate that we are enumerating codec infos but on decoder/encoder classes. We could do BitmapCodecInfo.GetAllDecoderInfos() and BitmapCodecInfo.GetAllEncoderInfos() where "All" is not very helfpul word, perhaps "Installed" or "Enabled" or "Supported" would be better, or we just drop it.

Alternatively, we could introduce BitmapDecoderInfo and BitmapEncoderInfo classes and have the methods there.

We should also have menas to create BitmapDecoder/Encoder from the info.

udaken commented 1 year ago

While I recognize the need and very much support the ability to enumerate decoders and encoders, I think the API could be a bit better. First it is a non-trivial operation so perhaps it should not be a property but a method. This would also allow you to control the enumeration options in the future. Then it is a bit unfortunate that we are enumerating codec infos but on decoder/encoder classes. We could do BitmapCodecInfo.GetAllDecoderInfos() and BitmapCodecInfo.GetAllEncoderInfos() where "All" is not very helfpul word, perhaps "Installed" or "Enabled" or "Supported" would be better, or we just drop it.

I fully agree with your point. "Installed" and "Available" are better descriptors of the procedure than "All".

The native IWICImagingFactory::CreateComponentEnumerator method allows WICComponentEnumerateOptions to be specified, so a method that allows future overloading to be added would be better.

I change Suggestion to BitmapCodecInfo.GetInstalledDecoderInfos()/BitmapCodecInfo.GetInstalledEncoderInfos().

udaken commented 1 year ago

The native IWICImagingFactory::CreateComponentEnumerator method allows WICComponentEnumerateOptions to be specified, so a method that allows future overloading to be added would be better.

This is an excellent suggestion that will be intuitive to use. I will add this to Alternative Designs.

We should also have menas to create BitmapDecoder/Encoder from the info.

Given the BitmapCodecInfo, there is already a way to create Y using the ContainerFormat property and BitmapDecoder.Create(Guid containerFormat)/BitmapEncoder.Create(Guid containerFormat), there is already a way to create BitmapDecoder/BitmapEncoder.

It would be more intuitive if there were an BitmapDecoderInfo.CreateDecoder()/BitmapEncoderInfo.CreateEncoder().