2009-09-09 16 views
74

Estoy cargando los bytes binarios del disco duro del archivo de imagen y cargándolo en un objeto Bitmap. ¿Cómo encuentro el tipo de imagen [JPEG, PNG, BMP, etc.] del objeto Bitmap?Buscar formato de imagen utilizando el objeto Bitmap en C#

Parece trivial. Pero, ¡no pude resolverlo!

¿Hay un enfoque alternativo?

Valora tu respuesta.

ACTUALIZADO CORRECTO SOLUCIÓN:

@CMS: Gracias por la respuesta correcta!

Código de muestra para lograr esto.

using (MemoryStream imageMemStream = new MemoryStream(fileData)) 
{ 
    using (Bitmap bitmap = new Bitmap(imageMemStream)) 
    { 
     ImageFormat imageFormat = bitmap.RawFormat; 
     if (bitmap.RawFormat.Equals(System.Drawing.Imaging.ImageFormat.Jpeg)) 
      //It's a JPEG; 
     else if (bitmap.RawFormat.Equals(System.Drawing.Imaging.ImageFormat.Png)) 
      //It's a PNG; 
    } 
} 
+3

Se podría añadir el espacio de nombres 'System.Drawing.Imaging' a su uso de directivas, para hacer las comprobaciones formato menos verboso ... – CMS

+0

@CMS: ¡De acuerdo! Quería mostrar el espacio de nombre completo para obtener información adicional. – pencilslate

+1

Hmmm ... Probé la misma técnica, pero no funciona. Tengo un PNG cargado y cuando comparo su valor de RawFormat en todas las instancias de ImageFormat. *, Ninguno de ellos coincide. El valor real de RawFormat es {b96b3caf-0728-11d3-9d7b-0000f81ef32e}. –

Respuesta

93

Si desea conocer el formato de una imagen, se puede cargar el archivo con la clase Image, y comprobar su propiedad RawFormat:

using(Image img = Image.FromFile(@"C:\path\to\img.jpg")) 
{ 
    if (img.RawFormat.Equals(System.Drawing.Imaging.ImageFormat.Jpeg)) 
    { 
     // ... 
    } 
} 
+26

Nota: Parece que 'img.RawFormat == ImageFormat.Jpeg' no funciona. Usted * tiene * que usar 'img.RawFormat.Equals (ImageFormat.Jpeg)'. –

+0

@BlueRaja, Sí, ¿por qué es eso? ¿No es cierto que la mayoría de las clases .NET anulan el método Equals() y el operador? O, tal vez, estoy fraseando mal: ¿.NET no usa el método .Equals() de forma predeterminada cuando usa el operador ==? ¿Soy incorrecto? – Pandincus

+0

Gah! No * me pregunto * que no estaba funcionando. Supuse que == hizo el truco. ¡Maldita sea! Gracias chicos, me han ahorrado un montón de tiempo en este momento. –

2

Simplemente hablando no se puede. La razón por la cual es que Bitmap es un tipo de imagen de la misma manera que JPEG, PNG, etc. Una vez que cargue una imagen en un mapa de bits, aparecerá la imagen del formato de mapa de bits. No hay forma de mirar un mapa de bits y entender la codificación original de la imagen (si es incluso diferente a Bitmap).

+0

Creo que es este caso Bitmap (confusamente) es el nombre de una clase en C#. La clase Bitmap contiene una imagen, que presumiblemente puede jpg, giff, bmp, etc. En cualquier otra circunstancia, sí, estás absolutamente en lo cierto. – DarcyThomas

5

por supuesto que puede. ImageFormat no significa mucho. ImageCodecInfo tiene mucho más significado.

red_dot.png

red_dot.png

<a href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg=="> 
    <img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==" alt="red_dot.png" title="red_dot.png"/> 
</a> 

código: salida

using System.Linq; 

//... 

//get image 
var file_bytes = System.Convert.FromBase64String(@"iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg=="); 
var file_stream = new System.IO.MemoryStream(file_bytes); 
var file_image = System.Drawing.Image.FromStream(file_stream); 

//list image formats 
var image_formats = typeof(System.Drawing.Imaging.ImageFormat).GetProperties(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static).ToList().ConvertAll(property => property.GetValue(null, null)); 
System.Diagnostics.Debug.WriteLine(image_formats.Count, "image_formats"); 
foreach(var image_format in image_formats) { 
    System.Diagnostics.Debug.WriteLine(image_format, "image_formats"); 
} 

//get image format 
var file_image_format = typeof(System.Drawing.Imaging.ImageFormat).GetProperties(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static).ToList().ConvertAll(property => property.GetValue(null, null)).Single(image_format => image_format.Equals(file_image.RawFormat)); 
System.Diagnostics.Debug.WriteLine(file_image_format, "file_image_format"); 

//list image codecs 
var image_codecs = System.Drawing.Imaging.ImageCodecInfo.GetImageDecoders().ToList(); 
System.Diagnostics.Debug.WriteLine(image_codecs.Count, "image_codecs"); 
foreach(var image_codec in image_codecs) { 
    System.Diagnostics.Debug.WriteLine(image_codec.CodecName + ", mime: " + image_codec.MimeType + ", extension: " + @image_codec.FilenameExtension, "image_codecs"); 
} 

//get image codec 
var file_image_format_codec = System.Drawing.Imaging.ImageCodecInfo.GetImageDecoders().ToList().Single(image_codec => image_codec.FormatID == file_image.RawFormat.Guid); 
System.Diagnostics.Debug.WriteLine(file_image_format_codec.CodecName + ", mime: " + file_image_format_codec.MimeType + ", extension: " + file_image_format_codec.FilenameExtension, "image_codecs", "file_image_format_type"); 

de depuración:

image_formats: 10 
image_formats: MemoryBMP 
image_formats: Bmp 
image_formats: Emf 
image_formats: Wmf 
image_formats: Gif 
image_formats: Jpeg 
image_formats: Png 
image_formats: Tiff 
image_formats: Exif 
image_formats: Icon 
file_image_format: Png 
image_codecs: 8 
image_codecs: Built-in BMP Codec, mime: image/bmp, extension: *.BMP;*.DIB;*.RLE 
image_codecs: Built-in JPEG Codec, mime: image/jpeg, extension: *.JPG;*.JPEG;*.JPE;*.JFIF 
image_codecs: Built-in GIF Codec, mime: image/gif, extension: *.GIF 
image_codecs: Built-in EMF Codec, mime: image/x-emf, extension: *.EMF 
image_codecs: Built-in WMF Codec, mime: image/x-wmf, extension: *.WMF 
image_codecs: Built-in TIFF Codec, mime: image/tiff, extension: *.TIF;*.TIFF 
image_codecs: Built-in PNG Codec, mime: image/png, extension: *.PNG 
image_codecs: Built-in ICO Codec, mime: image/x-icon, extension: *.ICO 
Built-in PNG Codec, mime: image/png, extension: *.PNG 
+0

¡Buen hallazgo Alex! Aunque parece desordenado, pero ve lo básico convertido en un par de métodos de extensión limpia a continuación. –

41

Aquí es mi método de extensión. Espero que esto ayude a alguien.

public static System.Drawing.Imaging.ImageFormat GetImageFormat(this System.Drawing.Image img) 
    {    
     if (img.RawFormat.Equals(System.Drawing.Imaging.ImageFormat.Jpeg)) 
      return System.Drawing.Imaging.ImageFormat.Jpeg; 
     if (img.RawFormat.Equals(System.Drawing.Imaging.ImageFormat.Bmp)) 
      return System.Drawing.Imaging.ImageFormat.Bmp; 
     if (img.RawFormat.Equals(System.Drawing.Imaging.ImageFormat.Png)) 
      return System.Drawing.Imaging.ImageFormat.Png; 
     if (img.RawFormat.Equals(System.Drawing.Imaging.ImageFormat.Emf)) 
      return System.Drawing.Imaging.ImageFormat.Emf; 
     if (img.RawFormat.Equals(System.Drawing.Imaging.ImageFormat.Exif)) 
      return System.Drawing.Imaging.ImageFormat.Exif; 
     if (img.RawFormat.Equals(System.Drawing.Imaging.ImageFormat.Gif)) 
      return System.Drawing.Imaging.ImageFormat.Gif; 
     if (img.RawFormat.Equals(System.Drawing.Imaging.ImageFormat.Icon)) 
      return System.Drawing.Imaging.ImageFormat.Icon; 
     if (img.RawFormat.Equals(System.Drawing.Imaging.ImageFormat.MemoryBmp)) 
      return System.Drawing.Imaging.ImageFormat.MemoryBmp; 
     if (img.RawFormat.Equals(System.Drawing.Imaging.ImageFormat.Tiff)) 
      return System.Drawing.Imaging.ImageFormat.Tiff; 
     else 
      return System.Drawing.Imaging.ImageFormat.Wmf;    
    } 
+2

No puedo creer que el .NET Framework no tenga esto incorporado y que esta sea la única forma. Estoy realmente en shock. – simonlchilds

1

Basado en el trabajo de Alex anterior (que llegan a votar como la solución, ya que es una línea - pero no puede votar todavía jaja), me ocurrió con la siguiente función de una biblioteca de imágenes. Requiere 4.0

Public Enum Formats 
    Unknown 
    Bmp 
    Emf 
    Wmf 
    Gif 
    Jpeg 
    Png 
    Tiff 
    Icon 
    End Enum 

    Public Shared Function ImageFormat(ByVal Image As System.Drawing.Image) As Formats 
    If Not System.Enum.TryParse(Of Formats)(System.Drawing.Imaging.ImageCodecInfo.GetImageDecoders().ToList().[Single](Function(ImageCodecInfo) ImageCodecInfo.FormatID = Image.RawFormat.Guid).FormatDescription, True, ImageFormat) Then 
     Return Formats.Unknown 
    End If 
    End Function 
11

aquí está mi código para esto. Primero debe cargar la imagen completa o el encabezado (primeros 4 bytes) en una matriz de bytes.

public enum ImageFormat 
{ 
    Bmp, 
    Jpeg, 
    Gif, 
    Tiff, 
    Png, 
    Unknown 
} 

public static ImageFormat GetImageFormat(byte[] bytes) 
{ 
    // see http://www.mikekunz.com/image_file_header.html 
    var bmp = Encoding.ASCII.GetBytes("BM");  // BMP 
    var gif = Encoding.ASCII.GetBytes("GIF"); // GIF 
    var png = new byte[] { 137, 80, 78, 71 }; // PNG 
    var tiff = new byte[] { 73, 73, 42 };   // TIFF 
    var tiff2 = new byte[] { 77, 77, 42 };   // TIFF 
    var jpeg = new byte[] { 255, 216, 255, 224 }; // jpeg 
    var jpeg2 = new byte[] { 255, 216, 255, 225 }; // jpeg canon 

    if (bmp.SequenceEqual(bytes.Take(bmp.Length))) 
     return ImageFormat.Bmp; 

    if (gif.SequenceEqual(bytes.Take(gif.Length))) 
     return ImageFormat.Gif; 

    if (png.SequenceEqual(bytes.Take(png.Length))) 
     return ImageFormat.Png; 

    if (tiff.SequenceEqual(bytes.Take(tiff.Length))) 
     return ImageFormat.Tiff; 

    if (tiff2.SequenceEqual(bytes.Take(tiff2.Length))) 
     return ImageFormat.Tiff; 

    if (jpeg.SequenceEqual(bytes.Take(jpeg.Length))) 
     return ImageFormat.Jpeg; 

    if (jpeg2.SequenceEqual(bytes.Take(jpeg2.Length))) 
     return ImageFormat.Jpeg; 

    return ImageFormat.Unknown; 
} 
+1

Se debe verificar JPEG para {255, 216, 255}. Aquí hay información http://en.wikipedia.org/wiki/JPEG – Mirodil

0

Un par de métodos de extensión limpias en el tipo Image para determinar esto, basado en el hallazgo de Alex anterior (ImageCodecInfo.GetImageDecoders()).

Esto está altamente optimizado después de la primera llamada, ya que el ImageCodecsDictionary estático se guarda en la memoria (pero solo después de que se haya usado una vez).

public static class ImageCodecInfoX 
{ 

    private static Dictionary<Guid, ImageCodecInfoFull> _imageCodecsDictionary; 

    public static Dictionary<Guid, ImageCodecInfoFull> ImageCodecsDictionary 
    { 
     get 
     { 
      if (_imageCodecsDictionary == null) { 
       _imageCodecsDictionary = 
        ImageCodecInfo.GetImageDecoders() 
        .Select(i => { 
         var format = ImageFormats.Unknown; 
         switch (i.FormatDescription.ToLower()) { 
          case "jpeg": format = ImageFormats.Jpeg; break; 
          case "png": format = ImageFormats.Png; break; 
          case "icon": format = ImageFormats.Icon; break; 
          case "gif": format = ImageFormats.Gif; break; 
          case "bmp": format = ImageFormats.Bmp; break; 
          case "tiff": format = ImageFormats.Tiff; break; 
          case "emf": format = ImageFormats.Emf; break; 
          case "wmf": format = ImageFormats.Wmf; break; 
         } 
         return new ImageCodecInfoFull(i) { Format = format }; 
        }) 
        .ToDictionary(c => c.CodecInfo.FormatID); 
      } 
      return _imageCodecsDictionary; 
     } 
    } 

    public static ImageCodecInfoFull CodecInfo(this Image image) 
    { 
     ImageCodecInfoFull codecInfo = null; 

     if (!ImageCodecsDictionary.TryGetValue(image.RawFormat.Guid, out codecInfo)) 
      return null; 
     return codecInfo; 
    } 

    public static ImageFormats Format(this Image image) 
    { 
     var codec = image.CodecInfo(); 
     return codec == null ? ImageFormats.Unknown : codec.Format; 
    } 
} 

public enum ImageFormats { Jpeg, Png, Icon, Gif, Bmp, Emf, Wmf, Tiff, Unknown } 

/// <summary> 
/// Couples ImageCodecInfo with an ImageFormats type. 
/// </summary> 
public class ImageCodecInfoFull 
{ 
    public ImageCodecInfoFull(ImageCodecInfo codecInfo = null) 
    { 
     Format = ImageFormats.Unknown; 
     CodecInfo = codecInfo; 
    } 

    public ImageCodecInfo CodecInfo { get; set; } 

    public ImageFormats Format { get; set; } 

} 
0

un raro problema que tuvimos cuando yo estaba tratando de obtener el tipo MIME utilizando imagecodeinfo .. para algunos archivos png los GUID no eran exactamente iguales ...

primero me marchaba con el ImageCodecinfo y si el código no encuentra el formato de imagen, entonces comparé el formato de imagen usando la solución de Matthias Wuttke.

si tanto la solución mencionada no se utiliza el método de extensión para obtener el tipo de archivo MIME ..

si cambia el tipo MIME a continuación, el archivo también cambia, nos cálculo de la suma de comprobación de los archivos descargados para que coincida con el suma de comprobación del archivo original en el servidor ... así que para nosotros fue importante obtener el archivo correcto como salida.

0

No me molesto en el tema anterior, pero para completar esta discusión, quiero compartir mi forma de consultar todos los formatos de imagen, conocidos por windows.

using System.Diagnostics; 
using System.Drawing; 
using System.Drawing.Imaging; 

public static class ImageExtentions 
{ 
    public static ImageCodecInfo GetCodecInfo(this System.Drawing.Image img) 
    { 
     ImageCodecInfo[] decoders = ImageCodecInfo.GetImageDecoders(); 
     foreach (ImageCodecInfo decoder in decoders) 
      if (img.RawFormat.Guid == decoder.FormatID) 
       return decoder; 
     return null; 
    } 
} 

Ahora se puede utilizar como una extensión de imagen como se muestra a continuación:

public void Test(Image img) 
{ 
    ImageCodecInfo info = img.GetCodecInfo(); 
    if (info == null) 
     Trace.TraceError("Image format is unkown"); 
    else 
     Trace.TraceInformation("Image format is " + info.FormatDescription); 
} 
Cuestiones relacionadas