Определить тип файла изображения

Я загружаю некоторые изображения из службы, которая не всегда включает тип содержимого и не предоставляет расширение для файла, который я загружаю (ugh, не спрашивайте).

Каков наилучший способ определения формата изображения в .NET?

Приложение, которое читает эти загруженные изображения, должно иметь правильное расширение файла или все ад разрывается.

Вероятно, более простым подходом было бы использовать Image.FromFile (), а затем использовать свойство RawFormat, поскольку он уже знает о волшебных битах в заголовках для наиболее распространенных форматов, например:

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 

Все форматы изображений устанавливают начальные байты на определенное значение:

  • JPG: 0xFF 0xD8
  • PNG: 0x89 0x50 0x4E 0x47 0x0D 0x0A 0x1A 0x0A
  • GIF: ‘G’ ‘I’ ‘F’

Найдите «формат файла jpg», заменив jpg на другие форматы файлов, которые вам нужно идентифицировать.

Как рекомендует Garth, существует firebase database таких «волшебных чисел», показывающая тип файла многих файлов. Если вам нужно обнаружить множество разных типов файлов, стоит посмотреть его, чтобы найти нужную вам информацию. Если вам нужно расширить это, чтобы охватить многие, многие типы файлов, посмотрите на связанную команду файла, которая реализует механизм для правильной работы с базой данных (это нетривиально для многих форматов файлов и является почти статистическим процессом)

-Адам

Вы можете использовать код ниже без ссылки на System.Drawing и ненужное создание объекта Image. Также вы можете использовать решение Alex даже без streamа и ссылки System.IO.

 public enum ImageFormat { bmp, jpeg, gif, tiff, png, unknown } public static ImageFormat GetImageFormat(Stream stream) { // see http://sofru.miximages.com/.net/ 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; } 

Адам указывает в правильном направлении.

Если вы хотите узнать, как воспринимать почти любой файл , посмотрите на базу данных за file командой на компьютере UNIX, Linux или Mac OS X.

file использует базу данных «магических чисел» – эти начальные байты, перечисленные Адамом, – для определения типа файла. man file скажет вам, где найти базу данных на вашем компьютере, например /usr/share/file/magic . man magic скажет вам свой формат .

Вы можете написать свой собственный код обнаружения на основе того, что вы видите в базе данных, использовать предварительно упакованные библиотеки (например, python-magic ), или – если вы действительно предприимчивы – реализуете .NET-версию libmagic . Я не мог найти его, и надеюсь, что другой член может указать на него.

Если у вас нет машины UNIX, firebase database выглядит так:

 # PNG [Portable Network Graphics, или PNG не GIF] изображения
 # (Грег Рулофс, [email protected])
 # (Альберт Кахалан, [email protected])
 #
 # 137 PNG \ r \ n ^ Z \ n [длина 4 байта] HEAD [данные HEAD] [HEAD crc] ...
 #
 0 строка \ x89PNG Данные изображения PNG,
 > 4 принадлежат! 0x0d0a1a0a CORRUPTED,
 > 4 принадлежат 0x0d0a1a0a
 >> 16 принадлежат x% ld x
 >> 20 принадлежат x% ld,
 >> 24 байта x% d-бит
 >> 25 байт 0 gradleаций серого,
 >> 25 байт 2 \ b / цвет RGB,
 >> 25 байт 3 colormap,
 >> 25 байт 4 серый + альфа,
 >> 25 байт 6 \ b / цвет RGBA,
 # >> 26 байт 0 deflate / 32K,
 >> 28 байт 0 без чередования
 >> 28 байт 1 с чересстрочной разверткой
 1 строка PNG PNG данные изображения, CORRUPTED

 # GIF
 0 строк данных GIF8 GIF
 > 4 строки 7a \ b, версия 8% s,
 > 4 строки 9a \ b, версия 8% s,
 > 6 leshort> 0% hd x
 > 8 leshort> 0% hd
 #> 10 байт и 0x80 цвет,
 #> 10 байт & 0x07 = 0x00 2 цвета
 #> 10 байт & 0x07 = 0x01 4 цвета
 #> 10 байт & 0x07 = 0x02 8 цветов
 #> 10 байт & 0x07 = 0x03 16 цветов
 #> 10 байт & 0x07 = 0x04 32 цвета
 #> 10 байт & 0x07 = 0x05 64 цвета
 #> 10 байт & 0x07 = 0x06 128 цветов
 #> 10 байт & 0x07 = 0x07 256 цветов

Удачи!

Существует программный способ определения изображения MIMETYPE.

Существует class System.Drawing.Imaging.ImageCodecInfo .

Этот class имеет свойства MimeType и FormatID . Также у него есть метод GetImageEncoders, который возвращает коллекцию всех кодеров изображений. Легко создавать словарь типов mime, индексированных по идентификатору формата.

Класс System.Drawing.Image имеет свойство RawFormat типа System.Drawing.Imaging.ImageFormat, у которого есть свойство Guid, которое эквивалентно свойству FormatID classа System.Drawing.Imaging.ImageCodecInfo , и это ключ к принятию MIMETYPE из словаря.

Пример:

Статический метод создания словаря типов mime

 static Dictionary GetImageFormatMimeTypeIndex() { Dictionary ret = new Dictionary(); var encoders = System.Drawing.Imaging.ImageCodecInfo.GetImageEncoders(); foreach(var e in encoders) { ret.Add(e.FormatID, e.MimeType); } return ret; } 

Использование:

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

Попробуйте загрузить stream в System.IO.BinaryReader.

Затем вам нужно будет обратиться к спецификациям для каждого формата изображения, который вам нужен, и загрузить байт заголовка байтом для сравнения с спецификациями. Например, здесь приведены спецификации PNG

Добавлено: фактическая файловая структура для PNG.

  • Должен ли я использовать #include рядом с ?
  • Ограничение типа множественного типа (ИЛИ)
  • объект-литье с переменной типа
  • Как разрешить «должен быть экземпляр строки, строка, заданная» до PHP 7?
  • Как определить применение Lisp в Haskell?
  • Как изменить тип данных DataColumn в DataTable?
  • Как вы знаете переменный тип в java?
  • Тестирование, если объект имеет общий тип в C #
  • Строка не была признана действительным DateTime "format dd / MM / yyyy"
  • Использовать разницу типов
  • Преобразование hex в текстовое представление в десятичное число
  • Interesting Posts

    Лучший способ получить данные с компьютера без поддержки USB или Ethernet?

    Какое правило Firebase предотвратит дубликаты в коллекции на основе других полей?

    Как использовать интерфейс как ограничение типа C #?

    Ошибка сегментации при изменении строки с помощью указателей?

    вычисление двойных интегралов в R быстро

    Неродное разрешение размыто на ноутбуке

    Количество вхождений подстроки в NSString?

    Количество символов в текстовом поле

    Приложение типа контента / xml; charset = utf-8 ответного сообщения не соответствует типу содержимого привязки (text / xml; charset = utf-8)

    Экспорт classов, содержащих std :: objects (вектор, карта и т. Д.) Из dll

    Откройте Google Chrome в режиме инкогнито?

    Как я могу провести сравнение строк без учета регистра?

    Как я могу обойти «ошибку 0x80070522» при создании файлов в корневом каталоге диска C (C: \)?

    android java lang runtimeexception не удается подключиться к службе камеры

    Как просмотреть результаты моих заданий cron?

    Давайте будем гением компьютера.