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

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

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

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

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
50
0
29 977
6
Перейти к ответу Данный вопрос помечен как решенный

Ответы 6

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

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

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

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

Выполните поиск по запросу «формат файла jpg», заменив jpg на другие форматы файлов, которые вам необходимо определить.

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

-Адам

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

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

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

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

Если у вас нет под рукой UNIX-машины, база данных выглядит так:

# PNG [Portable Network Graphics, or "PNG's Not GIF"] images
# (Greg Roelofs, [email protected])
# (Albert Cahalan, [email protected])
#
# 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

Удачи!

Ответ принят как подходящий

Вероятно, более простым подходом было бы использовать 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

К вашему сведению, это также работает для потоков, использующих System.Drawing.Image.FromStream ()

jishi 23.06.2010 14:31

если вы находитесь в контексте веб-приложения, важно использовать полное имя или импортировать сборку, чтобы избежать путаницы с элементом управления Image ... System.Drawing.Image

MacGyver 22.01.2012 04:55

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

Есть класс System.Drawing.Imaging.ImageCodecInfo.

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

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

Пример:

Статический метод для создания словаря 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;
}

Использовать:

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

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

Вы можете использовать приведенный ниже код без ссылки на System.Drawing и ненужного создания объекта Image. Также вы можете использовать решение Алекс даже без потока и ссылки на 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;
}

есть ли аналогичная предсказуемая последовательность для pdf, чтобы мы могли добавить ее в этот список? Спасибо

user95227 15.01.2016 01:07

@ user95227, ага! См. Эту библиотеку: Мим-детектив. Подпись PDF - здесь.

Ivan Kochurkin 15.01.2016 16:57

Другие вопросы по теме