在WindowsForms世界中,您可以获得可用的图像编码器/解码器列表
System.Drawing.ImageCodecInfo.GetImageDecoders() / GetImageEncoders()
Run Code Online (Sandbox Code Playgroud)
我的问题是,有没有办法为WPF世界做类似的事情,这将允许我获得可用的列表
System.Windows.Media.Imaging.BitmapDecoder / BitmapEncoder
Run Code Online (Sandbox Code Playgroud)
您一定会喜欢 .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
Run Code Online (Sandbox Code Playgroud)
代码中有一条注释,用于添加其他程序集(例如,如果您支持插件)。此外,您还需要过滤解码器列表以删除:
System.Windows.Media.Imaging.LateBoundBitmapDecoder
Run Code Online (Sandbox Code Playgroud)
使用构造函数模式匹配进行更复杂的过滤是可能的,但我不想编写它。:-)
您现在需要做的就是实例化编码器和解码器来使用它们。此外,您可以通过检索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;
}
}
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
如果我错了,希望有人能纠正我,但我认为 WPF 中没有类似的东西。但希望这是技术进步使我们习惯的做事方式过时的众多案例之一。例如“如何为我的数字手表上弦?”
据我了解,为什么 ImageCodecInfo.GetImageDecoders() 在 System.Drawing 中是必需的,这与 System.Drawing 本身的混乱本质有关:System.Drawing 是 GDI+ 的托管包装器,而 GDI+ 是 GDI+ 的一部分的非托管包装器。 Win32 API。因此,在 Windows 中安装新的编解码器可能是有原因的,而 .NET 本身并不知道它。从 GetImageDecoders() 返回的只是一堆字符串,这些字符串通常会传递回 System.Drawing/GDI+,并用于查找和配置适当的 DLL 来读取/保存图像。
另一方面,在 WPF 中,标准编码器和解码器内置于框架中,如果我没记错的话,不要依赖任何不能保证作为框架的一部分安装的东西。以下类继承自 BitmapEncoder,并且可在 WPF 中开箱即用:BmpBitmapEncoder、GifBitmapEncoder、JpegBitmapEncoder、PngBitmapEncoder、TiffBitmapEncoder、WmpBitmapEncoder。所有相同格式都有 BitmapDecoder,还有 IconBitmapDecoder 和 LateBoundBitmapDecoder。
您可能正在处理我没有想象到的情况,但在我看来,如果您必须使用继承自 BitmapEncoder 但未包含在 WPF 中的类,那么您可能需要安装您自己的自定义类与您的申请。
希望这可以帮助。如果我遗漏了图片的必要部分,请告诉我。
| 归档时间: |
|
| 查看次数: |
3180 次 |
| 最近记录: |