2008-08-18 10 views
9

En WindowsForms mundo se puede obtener una lista de los codificadores de imagen/decodificadores disponibles con¿Cómo obtener la lista de BitmapEncoders/Decoders instalados (el mundo de WPF)?

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

Mi pregunta es, ¿hay alguna manera de hacer algo similar para el mundo de WPF que permitiría a mí para obtener una lista de los disponibles

System.Windows.Media.Imaging.BitmapDecoder/BitmapEncoder 

Respuesta

0

Esperemos que alguien me corrija si me equivoco, pero no creo que haya nada como eso en WPF. Pero esperamos que este sea uno de los muchos casos en que los avances en la tecnología han quedado obsoletos de la manera en que estamos acostumbrados a hacer las cosas. Me gusta "¿cómo enrollo mi reloj digital?"

A mi entender, la razón por la que ImageCodecInfo.GetImageDecoders() es necesario en System.Drawing tiene que ver con la naturaleza kludgy de System.Drawing: System.Drawing es un contenedor administrado alrededor de GDI +, que es un contenedor no administrado alrededor de una parte de la API de Win32. Así que podría haber una razón por la cual un códec nuevo se instalaría en Windows sin que .NET lo supiera inherentemente. Y lo que devuelve GetImageDecoders() es simplemente un conjunto de cadenas que normalmente se pasan a System.Drawing/GDI + y se usan para buscar y configurar el archivo DLL apropiado para leer/guardar su imagen.

Por otro lado, en WPF, los codificadores y decodificadores estándar están integrados en el marco, y, si no me equivoco, no depende de nada que no esté garantizado para ser instalado como parte de el marco. Las siguientes clases heredan de BitmapEncoder y están disponibles de fábrica con WPF: BmpBitmapEncoder, GifBitmapEncoder, JpegBitmapEncoder, PngBitmapEncoder, TiffBitmapEncoder, WmpBitmapEncoder. Hay BitmapDecoders para todos los mismos formatos, además de IconBitmapDecoder y LateBoundBitmapDecoder.

Puede que tenga que lidiar con un caso que no imagino, pero me parece que si tiene que usar una clase que hereda de BitmapEncoder pero no se incluyó con WPF, probablemente sea su propia clase personalizada que instalarías con tu aplicación.

Espero que esto ayude. Si me falta una parte necesaria de la imagen, házmelo saber.

+1

Solo estoy investigando este problema, y ​​te equivocas. La generación de imágenes WPF es lo mismo que System.Drawing: una envoltura administrada para cosas Win32, es decir, WIC (Windows Imaging Component). Ningún codificador/decodificador está integrado en el marco, y creo que nunca lo habrá (razones de rendimiento y reutilización del código, lo tienen todo en Windows). Simplemente olvidaron agregar funcionalidad para listar los formatos :(. – fejesjoco

+0

re: "¿cómo enrollo mi reloj digital?" Ahora hacen relojes digitales que usan su movimiento para cargar la batería. Entonces podrían hacer uno con una bobinadora. :) –

4

Tienes que amar la reflexión .NET. Trabajé en el equipo de WPF y no puedo pensar en nada mejor de lo que pensaba. El siguiente código produce esta lista en mi máquina:

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 

hay un comentario en el código dónde agregar montajes adicionales (si apoya a los plugins, por ejemplo). Asimismo, se desea filtrar la lista decodificador para eliminar:

System.Windows.Media.Imaging.LateBoundBitmapDecoder 

más sofisticados de filtrado usando constructor de coincidencia de patrones es posible, pero no tiene ganas de escribirlo. :-)

Todo lo que necesita hacer ahora es crear instancias de los codificadores y decodificadores para usarlos. Además, puede obtener mejores nombres recuperando la propiedad CodecInfo de los decodificadores de codificador. Esta clase le dará nombres legibles entre otros factoids.

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