Déterminer le type de fichier d'une image
-
09-06-2019 - |
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.
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:
- JPG: 0xFF 0xD8
- PNG: 0x89 0x50 0x4E 0x47 0x0D 0x0A 0x1A 0x0A
- GIF: 'G' 'I' 'F'
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.