2009-09-09 14 views
74

Sto caricando i byte binari del disco rigido del file di immagine e caricandolo in un oggetto Bitmap. Come trovo il tipo di immagine [JPEG, PNG, BMP ecc.] Dall'oggetto Bitmap?Trova il formato immagine utilizzando l'oggetto Bitmap in C#

Sembra banale. Ma non riuscivo a capirlo!

Esiste un approccio alternativo?

Apprezzo la tua risposta.

AGGIORNATO soluzione corretta:

@CMS: Grazie per la risposta corretta!

Codice di esempio per raggiungere questo obiettivo.

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

Si potrebbe aggiungere il namespace 'System.Drawing.Imaging' il vostro stato usando le direttive, per rendere i controlli del formato meno verbose ... – CMS

+0

@CMS: d'accordo! Volevo visualizzare lo spazio dei nomi completo per ulteriori informazioni. – pencilslate

+1

Hmmm ... Ho provato la stessa tecnica, ma non funziona. Ho caricato un file PNG e quando confronto il suo valore RawFormat su tutte le istanze ImageFormat. *, Nessuna di esse corrisponde. Il valore effettivo di RawFormat è {b96b3caf-0728-11d3-9d7b-0000f81ef32e}. –

risposta

93

Se volete sapere il formato di un'immagine, è possibile caricare il file con la classe Image, e verificare la sua proprietà RawFormat:

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

Nota: sembra che 'img.RawFormat == ImageFormat.Jpeg' non funzioni. Devi * usare * 'img.RawFormat.Equals (ImageFormat.Jpeg)'. –

+0

@BlueRaja, Sì, perché è così? La maggior parte delle classi .NET non sostituisce il metodo Equals() e l'operatore? Oppure, forse sto dicendo che è sbagliato - .NET non usa il metodo .Equals() per impostazione predefinita quando utilizza l'operatore ==? Sono errato? – Pandincus

+0

Gah! No * meraviglia * che non funzionava. Ho pensato == ha fatto il trucco. Dannazione! Grazie ragazzi, mi ha risparmiato un sacco di tempo proprio ora. –

2

Semplicemente parlando non è possibile. Il motivo per cui Bitmap è un tipo di immagine nello stesso modo in cui sono JPEG, PNG, ecc. Una volta caricata un'immagine in una bitmap, l'immagine del formato bitmap. Non c'è modo di guardare una bitmap e capire la codifica originale dell'immagine (se è addirittura diversa da Bitmap).

+0

Penso che questo caso Bitmap (in modo confuso) sia il nome di una classe in C#. La classe Bitmap contiene un'immagine, che presumibilmente può jpg, giff, bmp, ecc. In qualsiasi altra circostanza si hai assolutamente ragione. – DarcyThomas

5

certo che puoi. ImageFormat non significa molto. ImageCodecInfo ha molto più significato.

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> 

codice: uscita

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"); 

debug:

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

Buona scoperta Alex! Anche se questo sembra disordinato, ma vedi i principi fondamentali trasformati in un paio di metodi di estensione pulita di seguito. –

41

Ecco il mio metodo di estensione. Spero che questo aiuti qualcuno.

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

Non riesco a credere che il framework .NET non abbia questa funzionalità e che questo sia l'unico modo. Sono davvero sotto shock. – simonlchilds

1

Sulla base di lavoro di Alex sopra (che in realtà ho votato come la soluzione, dal momento che è una linea - ma non posso ancora votare haha), mi si avvicinò con la seguente funzione di una libreria di immagini. Richiede 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

ecco il mio codice per questo. Devi prima caricare l'immagine completa o l'intestazione (primi 4 byte) su un array di byte.

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

Il JPEG deve essere controllato per {255, 216, 255}. Ecco le informazioni http://en.wikipedia.org/wiki/JPEG – Mirodil

0

Un paio di metodi di estensione puliti sul tipo di Image per determinare questo, sulla base del ritrovamento di Alex sopra (ImageCodecInfo.GetImageDecoders()).

Questo è altamente ottimizzato dopo la prima chiamata, poiché il file ImageCodecsDictionary viene salvato in memoria (ma solo dopo essere stato utilizzato una volta).

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 problema strano ho affrontato quando stavo cercando di ottenere il tipo MIME utilizzando imagecodeinfo .. per i file png alcuni i GUID non erano esattamente lo stesso ...

prima stavo controllando con l'ImageCodecinfo e se il codice non trova l'imageformat, ho confrontato l'imageformat usando la soluzione di Matthias Wuttke.

se sia la soluzione di cui sopra non è riuscito poi utilizzato il metodo di estensione per ottenere il tipo di file mime ..

se il tipo MIME modifiche allora il file cambia anche, siamo stati il ​​calcolo del checksum file scaricati da abbinare con il checksum del file originale sul server .. quindi per noi era importante ottenere il file corretto come output.

0

Non preoccuparsi di un argomento vecchio, ma per completare questa discussione, voglio condividere il mio modo di interrogare i formati di immagine tutti, conosciuti da 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; 
    } 
} 

Ora è possibile utilizzarlo come un prolungamento immagine come illustrato di seguito:

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); 
} 
Problemi correlati