2008-08-18 11 views
9

В WindowsForms мире вы можете получить список доступных изображений кодеры/декодеры сКак получить список установленных BitmapEncoders/Decoders (мир WPF)?

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

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

System.Windows.Media.Imaging.BitmapDecoder/BitmapEncoder 

ответ

0

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

Насколько я понимаю, причина, по которой ImageCodecInfo.GetImageDecoders() необходима в System.Drawing, связана с kludgy-характером самого 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, это, вероятно, ваш собственный пользовательский класс которые вы установили бы с вашим приложением.

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

+1

Я просто исследую эту проблему, и вы ошибаетесь. Изображение WPF такое же, как System.Drawing: управляемая оболочка для файлов Win32, а именно WIC (компонент Windows Imaging). Кодер/декодер не встроен в фреймворк, и я думаю, что никогда не будет (соображений по повторному использованию производительности и кода, они все в Windows). Они просто забыли добавить функциональность, чтобы перечислить форматы :(. – fejesjoco 2011-04-07 16:55:13

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; 
        } 
       } 
      } 
     } 
    } 
} 

 Смежные вопросы

  • Нет связанных вопросов^_^