Использование С#, как я могу проверить файл, является jpeg? Должен ли я проверить расширение .jpg?
Спасибо
Использование С#, как я могу проверить файл, является jpeg? Должен ли я проверить расширение .jpg?
Спасибо
Несколько параметров:
Вы можете проверить расширение файла:
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)))
{
UInt16 soi = br.ReadUInt16(); // Start of Image (SOI) marker (FFD8)
UInt16 marker = br.ReadUInt16(); // JFIF marker (FFE0) or EXIF marker(FF01)
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;
}
}
Откройте файл как поток и найдите магический номер для JPEG.
Файлы изображений JPEG начинаются с FF D8 и с FF D9. Файлы JPEG/JFIF содержат код ASCII для "JFIF" (4A 46 49 46) в виде строки с нулевым завершением. Файлы JPEG/Exif содержат код ASCII для "Exif" (45 78 69 66) также как строка с нулевым завершением
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;
}
}
Вы можете попробовать загрузить файл в изображение, а затем проверить формат
Image img = Image.FromFile(filePath);
bool isBitmap = img.RawFormat.Equals(ImageFormat.Jpeg);
В качестве альтернативы вы можете открыть файл и проверить заголовок, чтобы получить тип
Вы можете найти документацию в формате файла jpeg, в частности информацию заголовка. Затем попробуйте прочитать эту информацию из файла и сравнить ее с ожидаемыми байтами заголовка jpeg.
Прочитайте байты заголовка. Эта статья содержит информацию о нескольких распространенных форматах изображений, включая JPEG:
Использование заголовков файлов изображений для проверки формата изображения
Как только у вас есть расширение, вы можете использовать регулярное выражение для его проверки.
^.*\.(jpg|JPG)$
Это будет проходить через каждый файл в текущем каталоге и будет выводиться, если любые найденные файлы с расширением 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");
}
}
}
В зависимости от контекста, в котором вы смотрите этот файл, вам нужно помнить, что вы не можете открыть файл, пока пользователь не скажет вам чтобы открыть его.
(Ссылка на запись блога Raymond Chen.)
Вы можете использовать Path.GetExtension Method.
Код здесь:
http://mark.michaelis.net/Blog/RetrievingMetaDataFromJPEGFilesUsingC.aspx
Показывает, как получить метаданные. Я предполагаю, что это создало бы исключение, если бы ваш образ не был допустимым JPEG.
Проверка расширения файла недостаточно, поскольку имя файла может быть ложным.
Быстрый и грязный способ - попробовать загрузить изображение с помощью класса Image и перехватить любые исключения:
Image image = Image.FromFile(@"c:\temp\test.jpg");
Это не идеально, поскольку вы можете получить любое исключение, такое как OutOfMemoryException, FileNotFoundException и т.д. и т.д.
Самый тщательный способ - обработать файл как двоичный файл и обеспечить соответствие заголовка формату JPG. Я уверен, что это описано где-то.
Лучше всего попытаться создать образ из него с помощью конструктора Drawing.Bitmap(string) и посмотреть, не получится ли это сделать или выбрасывает исключение. Проблема с некоторыми ответами такова: во-первых, расширение является чисто произвольным, это могут быть jpg, jpeg, jpe, bob, tim, что угодно. Во-вторых, просто использовать заголовок недостаточно, чтобы быть на 100% уверенным. Он может определенно определить, что файл не является jpeg, но не может гарантировать, что файл является jpeg, произвольный двоичный файл может иметь одну и ту же последовательность байтов в начале.
Просто возьмите файл носителя и проверьте:
private bool isJpeg()
{
string p = currFile.Headers.ContentType.MediaType;
return p.ToLower().Equals("image/jpeg") || p.ToLower().Equals("image/pjpeg") || p.ToLower().Equals("image/png");
}
после проверки расширения файла прочитайте первые четыре байта изображения и два последних байта изображения, как это, сделайте это для двух последних байтов для значения 255, 217 для другого файла это можно сделать Подтвердить изображение из файла на С# http://www.garykessler.net/library/file_sigs.html
// after check extention of file
byte[] ValidFileSignture = new byte[] { 255, 216, 255, 224 };
byte[] bufferforCheck = new byte[ValidFileSignture.Length];
Stream _inputStream = file.InputStream;
byte[] bufferforCheck1 = new byte[] { 255, 216, 255, 224 };
_inputStream.Read(bufferforCheck, 0, ValidFileSignture.Length);
if (!Enumerable.SequenceEqual(bufferforCheck, ValidFileSignture))
{
//file OK
}
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