Как получить список установленных BitmapEncoders / Decoders (мир WPF)? - PullRequest
10 голосов
/ 18 августа 2008

В мире WindowsForms вы можете получить список доступных кодировщиков / декодеров изображений с помощью

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

У меня вопрос, есть ли способ сделать что-то аналогичное для мира WPF, которое позволило бы мне получить список доступных

System.Windows.Media.Imaging.BitmapDecoder / BitmapEncoder

Ответы [ 2 ]

4 голосов
/ 20 августа 2008

Вы должны любить отражение .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;
                    }
                }
            }
        }
    }
}
0 голосов
/ 19 августа 2008

Надеюсь, кто-то исправит меня, если я ошибаюсь, но я не думаю, что в WPF есть что-то подобное. Но, надеюсь, это один из многих случаев, когда достижения в технологии устарели, когда мы привыкли что-то делать. Например, «как мне заводить мои цифровые часы?»

Насколько я понимаю, причина, по которой ImageCodecInfo.GetImageDecoders () необходима в System.Drawing, связана с хитрой природой System.Drawing: System.Drawing - это управляемая оболочка для GDI +, которая является неуправляемой оболочкой вокруг часть Win32 API. Таким образом, может быть причина, по которой новый кодек будет установлен в Windows, но .NET по сути не знает об этом. И то, что возвращается из GetImageDecoders (), это просто набор строк, которые обычно передаются обратно в System.Drawing / GDI + и используются для поиска и настройки соответствующей DLL для чтения / сохранения вашего изображения.

С другой стороны, в WPF стандартные кодеры и декодеры встроены в каркас, и, если я не ошибаюсь, не зависят от того, что не гарантировано будет установлено как часть фреймворк. Следующие классы наследуются от BitmapEncoder и доступны в стандартной комплектации с WPF: BmpBitmapEncoder, GifBitmapEncoder, JpegBitmapEncoder, PngBitmapEncoder, TiffBitmapEncoder, WmpBitmapEncoder. Существуют BitmapDecoders для всех тех же форматов, плюс IconBitmapDecoder и LateBoundBitmapDecoder.

Возможно, вы имеете дело с делом, которое я не представляю, но мне кажется, что если вам нужно использовать класс, который унаследован от BitmapEncoder, но не включен в WPF, это, вероятно, ваш собственный класс, который вы бы установить с вашим приложением.

Надеюсь, это поможет. Если мне не хватает необходимой части изображения, пожалуйста, дайте мне знать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...