2009-09-09 4 views
74

Ich lade die binären Bytes der Image-Datei Festplatte und laden Sie es in ein Bitmap-Objekt. Wie finde ich den Bildtyp [JPEG, PNG, BMP usw.] aus dem Bitmap-Objekt?Finden Sie Bildformat mit Bitmap-Objekt in C#

Sieht trivial aus. Aber, konnte es nicht herausfinden!

Gibt es einen alternativen Ansatz?

Schätzen Sie Ihre Antwort.

AKTUALISIERT richtige Lösung:

@CMS: Danke für die richtige Antwort!

Beispielcode, um dies zu erreichen.

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

Sie könnten den 'System.Drawing.Imaging' Namespace zu Ihrer Verwendung von Richtlinien hinzufügen, die Formatprüfungen machen weniger verbose ... – CMS

+0

@CMS: Einverstanden! Wollte den vollständigen Namespace für zusätzliche Informationen anzeigen. – pencilslate

+1

Hmmm ... Ich habe die gleiche Technik versucht, aber es funktioniert nicht. Ich habe ein PNG geladen und wenn ich seinen RawFormat-Wert mit allen Instanzen von ImageFormat. * Vergleiche, stimmt keines überein. Der tatsächliche RawFormat-Wert lautet {b96b3caf-0728-11d3-9d7b-0000f81ef32e}. –

Antwort

93

Wenn Sie das Format eines Bildes wissen möchten, können Sie die Datei mit der Image Klasse laden, und überprüfen Sie die RawFormat Eigenschaft:

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

Hinweis: Es scheint, dass 'img.RawFormat == ImageFormat.Jpeg' nicht funktioniert. Sie müssen * img.RawFormat.Equals (ImageFormat.Jpeg) '' verwenden. –

+0

@BlueRaja, Ja, warum ist das so? Überschreiben die meisten .NET-Klassen sowohl die Equals() -Methode als auch den Operator nicht? Oder vielleicht formuliere ich es falsch - benutzt .NET nicht die Methode .Equals(), wenn Sie den Operator == benutzen? Bin ich falsch? – Pandincus

+0

Gah! Nein Wunder, das hat nicht funktioniert. Ich nahm an == hat den Trick gemacht. Verdammt! Danke Jungs, rettete mir gerade jetzt eine Menge Zeit. –

2

Einfach gesagt können Sie nicht. Der Grund dafür ist, dass Bitmap eine Art von Bild ist, genauso wie JPEG, PNG, usw. Sobald Sie ein Bild in eine Bitmap geladen haben, wird das Bild des Bitmap-Formats angezeigt. Es gibt keine Möglichkeit, ein Bitmap zu betrachten und die ursprüngliche Codierung des Bildes zu verstehen (wenn es sich sogar von Bitmap unterscheidet).

+0

Ich denke, ist dies Fall Bitmap (verwirrend) ist der Name einer Klasse in C#. Die Bitmap-Klasse enthält ein Bild, das vermutlich jpg, giff, bmp usw. sein kann. In jedem anderen Fall sind Sie absolut richtig. – DarcyThomas

5

natürlich möglich. ImageFormat bedeutet nicht viel. ImageCodecInfo hat viel mehr Bedeutung.

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> 

Code:

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-Ausgabe:

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

Gut finden Alex! Obwohl dies chaotisch aussieht, sehen Sie unten die Grundlagen, die unten in ein paar saubere Erweiterungsmethoden umgewandelt wurden. –

41

Hier ist meine Erweiterungsmethode. Hoffe, dass das jemandem hilft.

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

Ich kann nicht glauben, dass das .NET-Framework dies nicht gebacken hat und dass dies der einzige Weg ist. Ich bin wirklich schockiert. – simonlchilds

1

Basierend auf Alex 'Arbeit über (die ich eigentlich als die Lösung wählen, da es eine Zeile ist - aber ich kann noch nicht haha ​​stimmen), kam ich auf die folgende Funktion für eine Bildbibliothek auf. Es erfordert 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

Hier ist mein Code dafür. Sie müssen zuerst das komplette Bild oder den Header (die ersten 4 Bytes) in ein Byte-Array laden.

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

JPEG muss auf {255, 216, 255} überprüft werden. Hier ist http://en.wikipedia.org/wiki/JPEG – Mirodil

0

Ein paar sauberer Erweiterungsmethoden auf Typen Image dies zur Bestimmung, basierend auf der Entdeckung von Alex oben (ImageCodecInfo.GetImageDecoders()).

Dies ist nach dem ersten Aufruf sehr optimiert, da das statische ImageCodecsDictionary im Speicher gespeichert wird (aber erst nachdem es einmal verwendet wurde).

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

eine seltsame Problem, das ich konfrontiert, als ich versuchte, den MIME-Typ .. mit imagecodeinfo zu bekommen für einige png die guids Dateien ...

zuerst mit dem ImageCodecinfo i war die Überprüfung nicht genau gleich waren und wenn code das imageformat nicht findet, habe ich das imageformat mit der lösung von Matthias Wuttke verglichen.

beide, wenn die oben genannte Lösung gescheitert verwendet dann die Erweiterung Methode, um die Datei MIME-Typ zu bekommen ..

wenn der MIME-Typ ändert dann auch die Datei ändert, wurden wir die heruntergeladenen Dateien Prüfsumme Berechnung mit dem übereinstimmen Prüfsumme der Originaldatei auf dem Server. Für uns war es wichtig, die richtige Datei als Ausgabe zu erhalten.

0

Nicht zu alten Thema zu belästigen, aber um diese Diskussion abzuschließen, möchte ich meinen Weg zur Abfrage teilen alle Bildformate, von Windows bekannt.

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

Jetzt können Sie es als ein Bild-Erweiterung verwenden, wie unten dargestellt:

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); 
} 
Verwandte Themen