Frage

Ich lade einige Bilder von einem Dienst herunter, der nicht immer einen Inhaltstyp enthält und keine Erweiterung für die Datei bereitstellt, die ich herunterlade (pfui, fragen Sie nicht).

Wie lässt sich das Bildformat in .NET am besten ermitteln?

Die Anwendung, die diese heruntergeladenen Bilder liest, muss eine korrekte Dateierweiterung haben, sonst bricht die Hölle los.

War es hilfreich?

Lösung

Ein wahrscheinlich einfacher Ansatz wäre Image.FromFile () zu verwenden und dann die RawFormat Eigenschaft verwenden, da sie bereits über die magischen Bits in dem Header für die gängigsten Formate wissen, wie folgen aus:

Image i = Image.FromFile("c:\\foo");
if (System.Drawing.Imaging.ImageFormat.Jpeg.Equals(i.RawFormat)) 
    MessageBox.Show("JPEG");
else if (System.Drawing.Imaging.ImageFormat.Gif.Equals(i.RawFormat))
    MessageBox.Show("GIF");
//Same for the rest of the formats

Andere Tipps

Alle Bildformate setzen ihr anfängliches Bytes auf einen bestimmten Wert:

Suche nach „jpg-Dateiformat“ ersetzt jpg mit der anderen Dateiformaten Sie müssen identifizieren.

Als Garth empfiehlt, gibt es eine Datenbank solcher ‚magischen Zahlen‘ die zeigt, Dateityp vielen Dateien. Wenn Sie viele verschiedene Dateitypen zu erkennen, haben es lohnt sich durch sie suchen, um die benötigten Informationen zu finden. Wenn Sie brauchen, dies viele, viele Dateitypen abdecken zu erweitern, sehen Sie die zugehörigen Dateibefehl die den Motor implementiert die Datenbank zu verwenden, richtig (es ist nicht trivial für viele Dateiformate und ist fast ein statistischer Prozess)

-Adam

Sie können Code verwenden, unten ohne Bezug von System.Drawing und unnötige Erzeugung von Objektbild. Sie können auch Alex Lösung auch ohne Strom und Referenz von System.IO verwenden.

public enum ImageFormat
{
    bmp,
    jpeg,
    gif,
    tiff,
    png,
    unknown
}

public static ImageFormat GetImageFormat(Stream stream)
{
    // 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

    var buffer = new byte[4];
    stream.Read(buffer, 0, buffer.Length);

    if (bmp.SequenceEqual(buffer.Take(bmp.Length)))
        return ImageFormat.bmp;

    if (gif.SequenceEqual(buffer.Take(gif.Length)))
        return ImageFormat.gif;

    if (png.SequenceEqual(buffer.Take(png.Length)))
        return ImageFormat.png;

    if (tiff.SequenceEqual(buffer.Take(tiff.Length)))
        return ImageFormat.tiff;

    if (tiff2.SequenceEqual(buffer.Take(tiff2.Length)))
        return ImageFormat.tiff;

    if (jpeg.SequenceEqual(buffer.Take(jpeg.Length)))
        return ImageFormat.jpeg;

    if (jpeg2.SequenceEqual(buffer.Take(jpeg2.Length)))
        return ImageFormat.jpeg;

    return ImageFormat.unknown;
}

Adam zeigt in genau die richtige Richtung.

Wenn Sie wissen möchten, wie man Sinn fast jede Datei , Blick auf die Datenbank hinter dem file Befehl auf einem UNIX, Linux oder Mac OS X-Maschine.

file verwendet eine Datenbank von „magischen Zahlen“ - diesem ersten Bytes Adam aufgelistet - ein Dateityp zu erfassen. man file werden Ihnen sagen, wo die Datenbank auf Ihrem Computer zu finden, zum Beispiel /usr/share/file/magic. man magic werden Ihnen sagen, sein Format .

Sie können entweder schreiben Sie Ihren eigenen Erkennungscode auf, was Sie in der Datenbank zu sehen, verwenden abgepackte Bibliotheken (zB python-magic ), oder - wenn Sie wirklich abenteuerlich - eine .NET-Version von libmagic implementieren. Ich konnte nicht finden, und hoffen, dass ein anderes Mitglied einer darauf hinweisen kann.

Falls Sie nicht über eine UNIX-Maschine handlich, die Datenbank wie folgt aussieht:

# PNG [Portable Network Graphics, or "PNG's Not GIF"] images
# (Greg Roelofs, newt@uchicago.edu)
# (Albert Cahalan, acahalan@cs.uml.edu)
#
# 137 P N G \r \n ^Z \n [4-byte length] H E A D [HEAD data] [HEAD crc] ...
#
0       string          \x89PNG         PNG image data,
>4      belong          !0x0d0a1a0a     CORRUPTED,
>4      belong          0x0d0a1a0a
>>16    belong          x               %ld x
>>20    belong          x               %ld,
>>24    byte            x               %d-bit
>>25    byte            0               grayscale,
>>25    byte            2               \b/color RGB,
>>25    byte            3               colormap,
>>25    byte            4               gray+alpha,
>>25    byte            6               \b/color RGBA,
#>>26   byte            0               deflate/32K,
>>28    byte            0               non-interlaced
>>28    byte            1               interlaced
1       string          PNG             PNG image data, CORRUPTED

# GIF
0       string          GIF8            GIF image data
>4      string          7a              \b, version 8%s,
>4      string          9a              \b, version 8%s,
>6      leshort         >0              %hd x
>8      leshort         >0              %hd
#>10    byte            &0x80           color mapped,
#>10    byte&0x07       =0x00           2 colors
#>10    byte&0x07       =0x01           4 colors
#>10    byte&0x07       =0x02           8 colors
#>10    byte&0x07       =0x03           16 colors
#>10    byte&0x07       =0x04           32 colors
#>10    byte&0x07       =0x05           64 colors
#>10    byte&0x07       =0x06           128 colors
#>10    byte&0x07       =0x07           256 colors

Viel Glück!

Es ist programmatisch Bild MIMETYPE zu bestimmen.

Es gibt Klasse System.Drawing.Imaging.ImageCodecInfo .

Diese Klasse hat Eigenschaften Mimetype und formatID . es hat auch eine Methode GetImageEncoders , die Sammlung aller Bildgeber liefern. Es ist leicht, Wörterbuch der Mime-Typen durch Format-ID indiziert zu erstellen.

Klasse System.Drawing.Image haben Eigenschaft RawFormat der Typ System.Drawing.Imaging.ImageFormat die Eigenschaft haben, Guid , die von der Eigenschaft entspricht formatID die Klasse System.Drawing.Imaging.ImageCodecInfo , und das ist der Schlüssel MIMETYPE von Wörterbuch zu nehmen.

Beispiel:

Statische Methode Wörterbuch von Mime-Typen erstellen

static Dictionary<Guid, string> GetImageFormatMimeTypeIndex()
{
  Dictionary<Guid, string> ret = new Dictionary<Guid, string>();

  var encoders = System.Drawing.Imaging.ImageCodecInfo.GetImageEncoders();

  foreach(var e in encoders)
  {
    ret.Add(e.FormatID, e.MimeType);
  }

  return ret;
}

Verwendung:

Dictionary<Guid, string> mimeTypeIndex = GetImageFormatMimeTypeIndex();

FileStream imgStream = File.OpenRead(path);
var image = System.Drawing.Image.FromStream(imgStream);
string mimeType = mimeTypeIndex[image.RawFormat.Guid];

Versuchen Sie, den Strom in ein System.IO.BinaryReader geladen.

Dann müssen Sie die Spezifikationen für jedes Bildformat Sie benötigen, und laden Sie die Header-Byte für Byte beziehen gegen die Spezifikationen zu vergleichen. Zum Beispiel sind hier die PNG Spezifikationen

hinzugefügt: Die tatsächliche Dateistruktur PNG.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top