Question

Je suis le téléchargement des images à partir d'un service qui n'est pas toujours inclure un type de contenu et ne fournit pas une extension pour le fichier je télécharge (oh non, ne me demandez pas pourquoi).

Quelle est la meilleure façon de déterminer le format de l'image dans .NET?

L'application qui est à la lecture de ces images téléchargées doit avoir une bonne extension de fichier ou tous l'enfer se déchaîne.

Était-ce utile?

La solution

Probablement plus facile serait d'utiliser l'Image.FromFile() et utiliser le RawFormat bien, car il sait déjà à propos de la magie de bits dans les en-têtes pour les formats les plus courants, comme ceci:

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

Autres conseils

Tous les formats d'image définir leurs premiers octets d'une valeur particulière:

Recherche pour "format de fichier jpg" remplacement de jpg avec les autres formats de fichier, vous devez identifier.

Comme Garth recommande, il y a un base de données de numéros de magie' indiquant le type de fichier de plusieurs fichiers.Si vous avez de détecter un grand nombre de différents types de fichiers, il est intéressant de regarder à travers pour trouver les informations dont vous avez besoin.Si vous avez besoin de s'étendre pour couvrir de nombreux, de nombreux types de fichiers, regardez les associés fichier de commande qui met en œuvre le moteur à utiliser correctement la base de données (c'est non trivial pour de nombreux formats de fichiers, et c'est presque une statistique des processus)

-Adam

Vous pouvez utiliser le code ci-dessous, sans référence de Système.Le dessin et la création inutile d'Image de l'objet.Vous pouvez également utiliser Alex de solution, même sans les flux de référence et du Système.IO.

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 est orienté dans le bon sens.

Si vous voulez savoir comment sens presque n'importe quel fichier, regardez la base de données derrière la file commande sur un UNIX, Linux, ou Mac OS X de la machine.

file utilise une base de données des “nombres magiques” — ces premiers octets Adam énumérés à sens le type d'un fichier. man file vais vous dire où trouver la base de données sur votre machine, par ex. /usr/share/file/magic. man magic va vous dire sa format.

Vous pouvez soit écrire votre propre code de détection basé sur ce que vous voyez dans la base de données, l'utilisation de pré-emballés bibliothèques (p. ex. python-magie), ou — si vous êtes vraiment aventureux, — mettre en place un .La version NET de libmagic.Je ne pouvais pas en trouver un, et l'espoir d'un autre membre peut point une.

Dans le cas où vous n'avez pas une machine UNIX à portée de main, la base de données ressemble à ceci:

# 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

Bonne chance!

Il est programmatique manière de déterminer le type mime de l'image.

Il est classe Système.De dessin.L'imagerie.ImageCodecInfo.

Cette classe ont des propriétés MimeType et FormatID.Il est également à avoir une méthode GetImageEncoders de retour de la collecte de l'ensemble des codeurs.Il est facile de créer le Dictionnaire des types mime indexé par le code de format.

Classe Système.De dessin.Image ont la propriété RawFormat de Type Système.De dessin.L'imagerie.ImageFormat qui ont la propriété Guid soit l'équivalent de la propriété FormatID de classe Système.De dessin.L'imagerie.ImageCodecInfo, et qui est la clé pour prendre le type mime à partir du dictionnaire.

Exemple:

Méthode statique pour créer le dictionnaire des types mime

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

Utilisation:

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

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

Essayez de charger le flux dans un Système.IO.BinaryReader.

Ensuite, vous devez vous référer au cahier des charges pour chaque format d'image dont vous avez besoin, et de charger l'en-tête octet par octet pour les comparer par rapport aux spécifications.Pour exemple voici le PNG spécifications

Ajouté:Le réel la structure de fichier pour PNG.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top