C # Как я могу проверить файл в формате JPEG? - PullRequest
29 голосов
/ 21 апреля 2009

Используя C #, как я могу проверить файл в формате JPEG? Должен ли я проверить расширение .jpg?

Спасибо

Ответы [ 16 ]

101 голосов
/ 21 апреля 2009

Несколько вариантов:

Вы можете проверить расширение файла:

static bool HasJpegExtension(string filename)
{
    // add other possible extensions here
    return Path.GetExtension(filename).Equals(".jpg", StringComparison.InvariantCultureIgnoreCase)
        || Path.GetExtension(filename).Equals(".jpeg", StringComparison.InvariantCultureIgnoreCase);
}

или проверьте правильность магического числа в заголовке файла:

static bool HasJpegHeader(string filename)
{
    using (BinaryReader br = new BinaryReader(File.Open(filename, FileMode.Open, FileAccess.Read)))
    {
        UInt16 soi = br.ReadUInt16();  // Start of Image (SOI) marker (FFD8)
        UInt16 marker = br.ReadUInt16(); // JFIF marker (FFE0) or EXIF marker(FFE1)

        return soi == 0xd8ff && (marker & 0xe0ff) == 0xe0ff;
    }
}

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

static bool IsJpegImage(string filename)
{
    try
    {
        using (System.Drawing.Image img = System.Drawing.Image.FromFile(filename)) 
        {           
            // Two image formats can be compared using the Equals method
            // See http://msdn.microsoft.com/en-us/library/system.drawing.imaging.imageformat.aspx
            //
            return img.RawFormat.Equals(System.Drawing.Imaging.ImageFormat.Jpeg);
        }
    }
    catch (OutOfMemoryException)
    {
        // Image.FromFile throws an OutOfMemoryException 
        // if the file does not have a valid image format or
        // GDI+ does not support the pixel format of the file.
        //
        return false;
    }
}
28 голосов
/ 21 апреля 2009

Откройте файл в виде потока и найдите магическое число для JPEG.

Файлы изображений JPEG начинаются с FF D8 и конец с FF D9. Файлы JPEG / JFIF содержит код ASCII для 'JFIF' (4A 46 49 46) в виде строки с нулевым окончанием. Файлы JPEG / Exif содержат код ASCII для «Exif» (45 78 69 66) также как завершенная нулем строка

26 голосов
/ 06 января 2012

OMG, многие из этих примеров кода неправильные, неправильные неправильные.

Файлы EXIF ​​имеют маркер 0xff * e1 *, файлы JFIF имеют маркер 0xff * e0 *. Таким образом, весь код, который использует 0xffe0 для обнаружения файла JPEG, пропустит все файлы EXIF.

Вот версия, которая обнаружит и то, и другое, и ее можно легко изменить, чтобы она возвращалась только для JFIF или только для EXIF. (Полезно, например, при попытке восстановить фотографии с iPhone).

    public static bool HasJpegHeader(string filename)
    {
        try
        {
            // 0000000: ffd8 ffe0 0010 4a46 4946 0001 0101 0048  ......JFIF.....H
            // 0000000: ffd8 ffe1 14f8 4578 6966 0000 4d4d 002a  ......Exif..MM.*    
            using (BinaryReader br = new BinaryReader(File.Open(filename, FileMode.Open, FileAccess.ReadWrite)))
            {
                UInt16 soi = br.ReadUInt16();  // Start of Image (SOI) marker (FFD8)
                UInt16 marker = br.ReadUInt16(); // JFIF marker (FFE0) EXIF marker (FFE1)
                UInt16 markerSize = br.ReadUInt16(); // size of marker data (incl. marker)
                UInt32 four = br.ReadUInt32(); // JFIF 0x4649464a or Exif  0x66697845

                Boolean isJpeg = soi == 0xd8ff && (marker & 0xe0ff) == 0xe0ff;
                Boolean isExif = isJpeg && four == 0x66697845;
                Boolean isJfif = isJpeg && four == 0x4649464a;

                if (isJpeg) 
                {
                    if (isExif)
                        Console.WriteLine("EXIF: {0}", filename);
                    else if (isJfif)
                        Console.WriteLine("JFIF: {0}", filename);
                    else
                        Console.WriteLine("JPEG: {0}", filename);
                }

                return isJpeg;
                return isJfif;
                return isExif;
            }
        }
        catch
        {
            return false;
        }
    }
13 голосов
/ 21 апреля 2009

Вы можете попробовать загрузить файл в изображение, а затем проверить формат

Image img = Image.FromFile(filePath);
bool isBitmap = img.RawFormat.Equals(ImageFormat.Jpeg);

В качестве альтернативы вы можете открыть файл и проверить заголовок, чтобы получить тип

4 голосов
/ 21 апреля 2009

Вы можете найти документацию по формату файла jpeg, в частности информацию о заголовке. Затем попробуйте прочитать эту информацию из файла и сравнить ее с ожидаемыми байтами заголовка jpeg.

3 голосов
/ 21 апреля 2009

Чтение байтов заголовка. Эта статья содержит информацию о нескольких распространенных графических форматах, включая JPEG:

Использование заголовков файлов изображений для проверки формата изображения

Информация заголовка JPEG

1 голос
/ 21 апреля 2009

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

(ссылка на запись в блоге Раймонда Чена.)

1 голос
/ 21 апреля 2009

Это будет циклически проходить через каждый файл в текущем каталоге и выводить, если найденные файлы с расширением JPG или JPEG являются изображениями в формате Jpeg.

      foreach (FileInfo f in new DirectoryInfo(".").GetFiles())
        {
            if (f.Extension.ToUpperInvariant() == ".JPG"
                || f.Extension.ToUpperInvariant() == ".JPEG")
            {
                Image image = Image.FromFile(f.FullName);

                if (image.RawFormat == ImageFormat.Jpeg)
                {
                    Console.WriteLine(f.FullName + " is a Jpeg image");
                }
            }
        }
1 голос
/ 21 апреля 2009

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

^.*\.(jpg|JPG)$
0 голосов
/ 09 ноября 2016
System.Web.MimeMapping.GetMimeMapping(filename).StartsWith("image/");
MimeMapping.GetMimeMapping produces these results:

file.jpg: image/jpeg
file.gif: image/gif
file.jpeg: image/jpeg
file.png: image/png
file.bmp: image/bmp
file.tiff: image/tiff
file.svg: application/octet-stream
...