11

WindowsForms の世界では、使用可能な画像エンコーダー/デコーダーのリストを取得できます

System.Drawing.ImageCodecInfo.GetImageDecoders() / GetImageEncoders()

私の質問は、WPF の世界で、利用可能な

System.Windows.Media.Imaging.BitmapDecoder / BitmapEncoder
4

2 に答える 2

4

.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;
                    }
                }
            }
        }
    }
}
于 2008-08-20T06:03:18.313 に答える
1

私が間違っている場合は誰かが私を修正してくれることを願っていますが、WPFにはそのようなものはないと思います。しかし、うまくいけば、これは、テクノロジーの進歩により、私たちが慣れ親しんできた方法が時代遅れになった多くのケースの 1 つです。「デジタル時計の巻き方は?」のように。

私の理解では、System.Drawing で ImageCodecInfo.GetImageDecoders() が必要な理由は、System.Drawing 自体の厄介な性質に関係しています。 Win32 API。そのため、.NET が本質的にそれを認識せずに Windows に新しいコーデックがインストールされる理由があるかもしれません。GetImageDecoders() から返されるのは、通常は System.Drawing/GDI+ に返される一連の文字列であり、画像の読み取り/保存に適切な DLL を見つけて構成するために使用されます。

一方、WPF では、標準のエンコーダーとデコーダーがフレームワークに組み込まれているため、フレームワークの一部としてインストールされることが保証されていないものには依存しないでください。次のクラスは BitmapEncoder から継承され、WPF ですぐに使用できます: BmpBitmapEncoder、GifBitmapEncoder、JpegBitmapEncoder、PngBitmapEncoder、TiffBitmapEncoder、WmpBitmapEncoder。すべて同じ形式の BitmapDecoder に加えて、IconBitmapDecoder と LateBoundBitmapDecoder があります。

私が想像していないケースに対処している可能性がありますが、BitmapEncoder から継承するが WPF に含まれていないクラスを使用する必要がある場合は、おそらく独自のカスタム クラスをインストールするようです。あなたのアプリケーションで。

お役に立てれば。写真の必要な部分が欠けている場合は、お知らせください。

于 2008-08-18T23:41:57.760 に答える