Skip to Content

Как определить формат изображения/графического файла?

Опубликовано в

Понадобилось мне давеча узнать формат изображений хранящихся в базе данных. Никаких опознавательных знаков к этим изображениям не прилагалось - просто блобы с кучей непонятных байтов. Первое, что пришло в голову - сохранить эти блобы на диск, и открывая их по очереди блокнотом определять формат по сигнатуре в начале файла. В принципе, идея оказалась вполне жизнеспособной, только очень уж невесело было просматривать многомегабайтные файлы в notepad'е. После надцатого файла я решил, что так дело не пойдет, и написал небольшую утилиту на C#, которая справляется с этой задачей куда лучше блокнота. Собственно, вот она:

  1. using System;
  2. using System.Drawing;
  3.  
  4. namespace ImageFormatVerifier
  5. {
  6.     class Program
  7.     {
  8.         static void Main(string[] args)
  9.         {
  10.             try
  11.             {
  12.            
  13.                 Image image = Image.FromFile(args[0]);
  14.                 var imageFormat = "";
  15.  
  16.                 if (System.Drawing.Imaging.ImageFormat.Bmp.Equals(image.RawFormat))
  17.                 {                
  18.                     imageFormat = "BMP";
  19.                 }
  20.  
  21.                 if (System.Drawing.Imaging.ImageFormat.Emf.Equals(image.RawFormat))
  22.                 {
  23.                     imageFormat = "EMF";
  24.                 }
  25.  
  26.                 if (System.Drawing.Imaging.ImageFormat.Gif.Equals(image.RawFormat))
  27.                 {
  28.                     imageFormat = "GIF";
  29.                 }
  30.  
  31.                 if (System.Drawing.Imaging.ImageFormat.Icon.Equals(image.RawFormat))
  32.                 {
  33.                     imageFormat = "ICON";
  34.                 }
  35.  
  36.                 if (System.Drawing.Imaging.ImageFormat.Jpeg.Equals(image.RawFormat))
  37.                 {
  38.                     imageFormat = "JPEG";
  39.                 }
  40.  
  41.                 if (System.Drawing.Imaging.ImageFormat.Png.Equals(image.RawFormat))
  42.                 {
  43.                     imageFormat = "PNG";
  44.                 }
  45.  
  46.                 if (System.Drawing.Imaging.ImageFormat.Tiff.Equals(image.RawFormat))
  47.                 {
  48.                     imageFormat = "TIFF";
  49.                 }
  50.  
  51.                 if (System.Drawing.Imaging.ImageFormat.Wmf.Equals(image.RawFormat))
  52.                 {
  53.                     imageFormat = "WMF";
  54.                 }
  55.                 if (imageFormat.Length == 0){
  56.                     imageFormat = "Unknown";
  57.                 }
  58.            
  59.                 Console.WriteLine(imageFormat);
  60.  
  61.             }                                        
  62.             catch
  63.             {
  64.  
  65.                 Console.WriteLine("Unable to load image from file");
  66.                 Environment.Exit(0);
  67.  
  68.             }
  69.  
  70.         }
  71.     }
  72. }
Также, можно скачать вариант для ленивых.

Использовать утилиту совсем не сложно:

C:\>ImageFormatVerifier.exe myimagefile.whatever
PNG
C:\>

Все.

Предложение рефактора

Я если честно не профи в C#, но немножко погуглив вроде нашёл что вместо многочисленной серии if можно написать как-то так:

imageFormat = image.RawFormat.ToString

RawFormat возвращает обект типа ImageFormat, а на нём переписан метод ToString. Хотя может где-то и ошибаюсь.

Я тоже не то чтобы профи в

Я тоже не то чтобы профи в шарпе, так что ничего страшного.

Так как вы предлагаете, я тоже пытался сделать, но дело в том, что
image.RawFormat.ToString()
возвращает GUID, а точнее строку типа такой:

[ImageFormat: b96b3cae-0728-11d3-9d7b-0000f81ef32e]

, а как расшифровать гуиды я так и не нашел.

Хотя, я, конечно, балбес. Только что погуглил по самому GUID'у и сразу же обнаружил кучу разных сайтов с расшифровкой, так что желающие могут сами сделать что-то вроде:

  1. ...
  2. switch (image.RawFormat.Guid)
  3.  
  4. {
  5.   case   new Guid("b96b3cae-0728-11d3-9d7b-0000f81ef32e"):
  6.                 ...
  7. }
  8. ...

Возможно, получится несколько красивее и короче моего варианта.

Красиво не получается. :(

Ну да. Красиво не получается. Sad

Единственное что, вроде тогда можно чтоб не искать Guid использовать ImageFormat.Jpeg

В никсах есть программа file, которая определяет тип файла

В никсах есть программа file, которая определяет тип файла. Наверняка имеется порт под винду.

bash$ file common/src/web/markerTransparent.png
common/src/web/markerTransparent.png: PNG image data, 20 x 34,
8-bit/color RGBA, non-interlaced

bash$ file common/src/web/banner.gif
common/src/web/banner.gif: GIF image data, version 89a, 644 x 41

Знаю о такой, она, вроде бы,

Знаю о такой, она, вроде бы, и в Cygwin'е есть. Но писать в тест кейсах - "поставьте Linux или Cygwin" не комильфо Smile

Под винду есть ещё TrID

Спасибо за ссылку. Неплохая

Спасибо за ссылку.

Неплохая программулина, правда есть забавные моменты, например, так в ее понимании выглядит JPG файл:

32.2% (.JPG) JFIF-EXIF JPEG Bitmap (5000/1/1)
25.8% (.JPG) JFIF JPEG Bitmap (4003/3)
19.3% (.JPG) JPEG Bitmap (3000/1)
16.1% (.MP3) MP3 audio (ID3 v1.x tag) (2500/1/1)
6.4% (.MP3) MP3 audio (1000/1)

И еще есть один не очень приятный момент:

License:
The program can be freely distribuited and is freeware for non commercial,
personal, research and educational use.
Contact the author for commercial use or commercialization of TrID or
TrID's definitions and contained informations.

 

Отправить комментарий

  • Адреса страниц и электронной почты автоматически преобразуются в ссылки.
  • Доступны HTML теги: <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd>
  • Строки и параграфы переносятся автоматически.
  • Pairs of<blockquote> tags will be styled as a block that indicates a quotation.
  • Textual smileys will be replaced with graphical ones.

Подробнее о форматировании