47 votes

Déterminer le type de fichier d'une image

Je télécharge des images à partir d'un service qui n'inclut pas toujours un type de contenu et ne fournit pas une extension pour le fichier que je télécharge (pouah, ne demandez pas).

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

L'application qui lit ces images téléchargées doit avoir une extension de fichier appropriée ou tout l'enfer se déchaîne.

55voto

Vinko Vrsalovic Points 116138

Une approche probablement plus facile consisterait à utiliser Image.FromFile (), puis la propriété RawFormat, car il connaît déjà les bits magiques 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
 

24voto

KvanTTT Points 1060

Vous pouvez utiliser le code ci-dessous sans référence à System.Drawing et à la création inutile d'objet Image. Vous pouvez aussi utiliser la solution Alex même sans flux ni référence de System.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;
}
 

22voto

Adam Davis Points 47683

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 une 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 l'étendre à 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)

8voto

Garth Kidd Points 2792

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 le 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 va vous dire où trouver la base de données sur votre machine, par exemple, /usr/share/file/magic. man magic va vous raconter son 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 (par exemple, 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, ou "PNG n'est Pas GIF"] images
# (Greg Roelofs, newt@uchicago.edu)
# (Albert Cahalan, acahalan@cs.uml.edu)
#
# 137 P N G \r \n ^Z \n [4 octets] H E A D [TÊTE de données] [CHEF de la crc] ...
#
0 string \x89PNG image PNG de données,
>4 appartiennent !0x0d0a1a0a CORROMPU,
>4 appartiennent 0x0d0a1a0a
>>16 appartiennent à x %ld x
>>20 appartiennent à x %ld,
>>24 octets x %d-bit
>>25 octet 0 en niveaux de gris,
>>25 octet 2 \b/couleur RVB,
>>25 octet 3 palettes,
>>25 octet 4 gris+alpha,
>>25 octet 6 \b/couleur RGBA,
#>>26 octet 0 dégonfler/32K,
>>28 octet 0 non entrelacé
>>28 octet 1 entrelacé
1 chaîne PNG PNG données d'image, CORROMPU

# GIF
0 chaîne GIF8 image GIF de données
>4 cordes 7a \b, la version 8% s,
>4 cordes 9a \b, la version 8% s,
>6 leshort >0 %hd x
>8 leshort >0 %hd
#>10 byte &0x80 couleur mappé,
#>10 byte&0x07 =0x00 2 couleurs
#>10 byte&0x07 =0x01 4 couleurs
#>10 byte&0x07 =0x02 8 couleurs
#>10 byte&0x07 =0x03 16 couleurs
#>10 byte&0x07 =0x04 32 couleurs
#>10 byte&0x07 =0x05 64 couleurs
#>10 byte&0x07 =0x06 128 couleurs
#>10 byte&0x07 =0x07 256 couleurs

Bonne chance!

3voto

slobodans Points 180

Il est programmatique façon de déterminer le type mime de l'image.

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

Cette classe ont des propriétés de type mime et FormatID. Il est également à avoir une méthode GetImageEncoders qui 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 De Système.De dessin.L'Image des biens RawFormat de Type Système.De dessin.L'imagerie.ImageFormat qui ont bien Guid qui est l'équivalent de la propriété FormatID de classe du 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];

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X