如何获取已安装的 BitmapEncoders/Decoders 列表(WPF 世界)?
Posted
技术标签:
【中文标题】如何获取已安装的 BitmapEncoders/Decoders 列表(WPF 世界)?【英文标题】:How to get list of installed BitmapEncoders/Decoders (the WPF world)? 【发布时间】:2010-09-06 02:43:45 【问题描述】:在 WindowsForms 世界中,您可以获得可用的图像编码器/解码器列表
System.Drawing.ImageCodecInfo.GetImageDecoders() / GetImageEncoders()
我的问题是,有没有办法为 WPF 世界做一些类似的事情,让我得到一个可用列表
System.Windows.Media.Imaging.BitmapDecoder / BitmapEncoder
【问题讨论】:
【参考方案1】:您必须喜欢 .NET 反射。我曾在 WPF 团队工作,我想不出有什么比这更好的了。以下代码在我的机器上生成此列表:
Bitmap Encoders:
System.Windows.Media.Imaging.BmpBitmapEncoder
System.Windows.Media.Imaging.GifBitmapEncoder
System.Windows.Media.Imaging.JpegBitmapEncoder
System.Windows.Media.Imaging.PngBitmapEncoder
System.Windows.Media.Imaging.TiffBitmapEncoder
System.Windows.Media.Imaging.WmpBitmapEncoder
Bitmap Decoders:
System.Windows.Media.Imaging.BmpBitmapDecoder
System.Windows.Media.Imaging.GifBitmapDecoder
System.Windows.Media.Imaging.IconBitmapDecoder
System.Windows.Media.Imaging.LateBoundBitmapDecoder
System.Windows.Media.Imaging.JpegBitmapDecoder
System.Windows.Media.Imaging.PngBitmapDecoder
System.Windows.Media.Imaging.TiffBitmapDecoder
System.Windows.Media.Imaging.WmpBitmapDecoder
代码中有一条注释可以添加其他程序集(例如,如果您支持插件)。此外,您还需要过滤要删除的解码器列表:
System.Windows.Media.Imaging.LateBoundBitmapDecoder
使用构造函数模式匹配的更复杂的过滤是可能的,但我不想写它。 :-)
您现在需要做的就是实例化编码器和解码器以使用它们。此外,您可以通过检索编码器解码器的CodecInfo
属性来获得更好的名称。此类将在其他事实中为您提供人类可读的名称。
using System;
using System.Linq;
using System.Collections.Generic;
using System.Reflection;
using System.Windows.Media.Imaging;
namespace Codecs
class Program
static void Main(string[] args)
Console.WriteLine("Bitmap Encoders:");
AllEncoderTypes.ToList().ForEach(t => Console.WriteLine(t.FullName));
Console.WriteLine("\nBitmap Decoders:");
AllDecoderTypes.ToList().ForEach(t => Console.WriteLine(t.FullName));
Console.ReadKey();
static IEnumerable<Type> AllEncoderTypes
get
return AllSubclassesOf(typeof(BitmapEncoder));
static IEnumerable<Type> AllDecoderTypes
get
return AllSubclassesOf(typeof(BitmapDecoder));
static IEnumerable<Type> AllSubclassesOf(Type type)
var r = new Reflector();
// Add additional assemblies here
return r.AllSubclassesOf(type);
class Reflector
List<Assembly> assemblies = new List<Assembly>
typeof(BitmapDecoder).Assembly
;
public IEnumerable<Type> AllSubclassesOf(Type super)
foreach (var a in assemblies)
foreach (var t in a.GetExportedTypes())
if (t.IsSubclassOf(super))
yield return t;
【讨论】:
所以IWICImagingFactory.CreateComponentEnumerator
周围没有 WPF 包装器,检测比 Framework 晚的编解码器的唯一方法是 COM Interop?【参考方案2】:
如果我错了,希望有人能纠正我,但我认为 WPF 中没有类似的东西。但希望这是技术进步使我们习惯于做事的方式变得过时的众多案例之一。比如“如何给我的数字手表上弦?”
据我了解,在 System.Drawing 中需要 ImageCodecInfo.GetImageDecoders() 的原因与 System.Drawing 本身的笨拙性质有关:System.Drawing 是 GDI+ 的托管包装器,它是 GDI+ 的非托管包装器Win32 API 的一部分。因此,在 .NET 本身不知道的情况下,可能会在 Windows 中安装新的编解码器是有原因的。而从 GetImageDecoders() 返回的只是一堆字符串,通常会传回 System.Drawing/GDI+,并用于查找和配置适当的 DLL 以读取/保存您的图像。
另一方面,在 WPF 中,标准编码器和解码器内置于框架中,如果我没记错的话,不要依赖任何不能保证作为一部分安装的东西框架。以下类继承自 BitmapEncoder,并且可与 WPF 一起使用:BmpBitmapEncoder、GifBitmapEncoder、JpegBitmapEncoder、PngBitmapEncoder、TiffBitmapEncoder、WmpBitmapEncoder。所有相同格式都有 BitmapDecoder,还有 IconBitmapDecoder 和 LateBoundBitmapDecoder。
您可能正在处理我无法想象的情况,但在我看来,如果您必须使用从 BitmapEncoder 继承但 WPF 未包含的类,则可能是您自己的自定义类您将与您的应用程序一起安装。
希望这会有所帮助。如果我缺少图片的必要部分,请告诉我。
【讨论】:
我只是在研究这个问题,你错了。 WPF 映像与 System.Drawing 相同:Win32 内容的托管包装器,即 WIC(Windows 映像组件)。框架中没有内置编码器/解码器,我认为永远不会有(性能和代码重用原因,它们在 Windows 中都有)。他们只是忘记添加列出格式的功能:(。 re:“如何为我的数字手表上弦?”他们现在制造使用您的动作为电池充电的数字手表。所以他们可以用绕线机制作一个。 :)以上是关于如何获取已安装的 BitmapEncoders/Decoders 列表(WPF 世界)?的主要内容,如果未能解决你的问题,请参考以下文章