Я загружаю двоичные байты жесткого диска с файлом изображения и загружаю его в объект Bitmap. Как мне найти тип изображения [JPEG, PNG, BMP и т. Д.] Из объекта Bitmap?
Выглядит банально. Но не мог понять!
Есть ли альтернативный подход?
Оцените ваш ответ.
ОБНОВЛЕННОЕ ПРАВИЛЬНОЕ РЕШЕНИЕ:
@CMS: Спасибо за правильный ответ!
Пример кода для этого.
using (MemoryStream imageMemStream = new MemoryStream(fileData))
{
using (Bitmap bitmap = new Bitmap(imageMemStream))
{
ImageFormat imageFormat = bitmap.RawFormat;
if (bitmap.RawFormat.Equals(System.Drawing.Imaging.ImageFormat.Jpeg))
//It's a JPEG;
else if (bitmap.RawFormat.Equals(System.Drawing.Imaging.ImageFormat.Png))
//It's a PNG;
}
}
System.Drawing.Imaging
пространство имен к своим директивам using, чтобы сделать проверки формата менее подробными ...Ответы:
Если вы хотите узнать формат изображения, вы можете загрузить файл с помощью класса Image и проверить его свойство RawFormat :
using(Image img = Image.FromFile(@"C:\path\to\img.jpg")) { if (img.RawFormat.Equals(System.Drawing.Imaging.ImageFormat.Jpeg)) { // ... } }
источник
img.RawFormat == ImageFormat.Jpeg
это не работает. Вы должны использоватьimg.RawFormat.Equals(ImageFormat.Jpeg)
.==
ссылочное равенство не используетсяEquals
. Помимо использованияEquals
себя, вы можете использовать staticobject.Equals(obj1, obj2)
(который вызываетEquals
) для простой нулевой безопасности.Вот мой метод расширения. Надеюсь, это кому-то поможет.
public static System.Drawing.Imaging.ImageFormat GetImageFormat(this System.Drawing.Image img) { if (img.RawFormat.Equals(System.Drawing.Imaging.ImageFormat.Jpeg)) return System.Drawing.Imaging.ImageFormat.Jpeg; if (img.RawFormat.Equals(System.Drawing.Imaging.ImageFormat.Bmp)) return System.Drawing.Imaging.ImageFormat.Bmp; if (img.RawFormat.Equals(System.Drawing.Imaging.ImageFormat.Png)) return System.Drawing.Imaging.ImageFormat.Png; if (img.RawFormat.Equals(System.Drawing.Imaging.ImageFormat.Emf)) return System.Drawing.Imaging.ImageFormat.Emf; if (img.RawFormat.Equals(System.Drawing.Imaging.ImageFormat.Exif)) return System.Drawing.Imaging.ImageFormat.Exif; if (img.RawFormat.Equals(System.Drawing.Imaging.ImageFormat.Gif)) return System.Drawing.Imaging.ImageFormat.Gif; if (img.RawFormat.Equals(System.Drawing.Imaging.ImageFormat.Icon)) return System.Drawing.Imaging.ImageFormat.Icon; if (img.RawFormat.Equals(System.Drawing.Imaging.ImageFormat.MemoryBmp)) return System.Drawing.Imaging.ImageFormat.MemoryBmp; if (img.RawFormat.Equals(System.Drawing.Imaging.ImageFormat.Tiff)) return System.Drawing.Imaging.ImageFormat.Tiff; else return System.Drawing.Imaging.ImageFormat.Wmf; }
источник
вот мой код для этого. Вы должны сначала загрузить полное изображение или заголовок (первые 4 байта) в массив байтов.
public enum ImageFormat { Bmp, Jpeg, Gif, Tiff, Png, Unknown } public static ImageFormat GetImageFormat(byte[] bytes) { // 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 if (bmp.SequenceEqual(bytes.Take(bmp.Length))) return ImageFormat.Bmp; if (gif.SequenceEqual(bytes.Take(gif.Length))) return ImageFormat.Gif; if (png.SequenceEqual(bytes.Take(png.Length))) return ImageFormat.Png; if (tiff.SequenceEqual(bytes.Take(tiff.Length))) return ImageFormat.Tiff; if (tiff2.SequenceEqual(bytes.Take(tiff2.Length))) return ImageFormat.Tiff; if (jpeg.SequenceEqual(bytes.Take(jpeg.Length))) return ImageFormat.Jpeg; if (jpeg2.SequenceEqual(bytes.Take(jpeg2.Length))) return ImageFormat.Jpeg; return ImageFormat.Unknown; }
источник
конечно вы можете.
ImageFormat
мало значит.ImageCodecInfo
имеет гораздо большее значение.red_dot.png
<a href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg=="> <img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==" alt="red_dot.png" title="red_dot.png"/> </a>
код:
using System.Linq; //... //get image var file_bytes = System.Convert.FromBase64String(@"iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg=="); var file_stream = new System.IO.MemoryStream(file_bytes); var file_image = System.Drawing.Image.FromStream(file_stream); //list image formats var image_formats = typeof(System.Drawing.Imaging.ImageFormat).GetProperties(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static).ToList().ConvertAll(property => property.GetValue(null, null)); System.Diagnostics.Debug.WriteLine(image_formats.Count, "image_formats"); foreach(var image_format in image_formats) { System.Diagnostics.Debug.WriteLine(image_format, "image_formats"); } //get image format var file_image_format = typeof(System.Drawing.Imaging.ImageFormat).GetProperties(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static).ToList().ConvertAll(property => property.GetValue(null, null)).Single(image_format => image_format.Equals(file_image.RawFormat)); System.Diagnostics.Debug.WriteLine(file_image_format, "file_image_format"); //list image codecs var image_codecs = System.Drawing.Imaging.ImageCodecInfo.GetImageDecoders().ToList(); System.Diagnostics.Debug.WriteLine(image_codecs.Count, "image_codecs"); foreach(var image_codec in image_codecs) { System.Diagnostics.Debug.WriteLine(image_codec.CodecName + ", mime: " + image_codec.MimeType + ", extension: " + @image_codec.FilenameExtension, "image_codecs"); } //get image codec var file_image_format_codec = System.Drawing.Imaging.ImageCodecInfo.GetImageDecoders().ToList().Single(image_codec => image_codec.FormatID == file_image.RawFormat.Guid); System.Diagnostics.Debug.WriteLine(file_image_format_codec.CodecName + ", mime: " + file_image_format_codec.MimeType + ", extension: " + file_image_format_codec.FilenameExtension, "image_codecs", "file_image_format_type");
вывод отладки:
image_formats: 10 image_formats: MemoryBMP image_formats: Bmp image_formats: Emf image_formats: Wmf image_formats: Gif image_formats: Jpeg image_formats: Png image_formats: Tiff image_formats: Exif image_formats: Icon file_image_format: Png image_codecs: 8 image_codecs: Built-in BMP Codec, mime: image/bmp, extension: *.BMP;*.DIB;*.RLE image_codecs: Built-in JPEG Codec, mime: image/jpeg, extension: *.JPG;*.JPEG;*.JPE;*.JFIF image_codecs: Built-in GIF Codec, mime: image/gif, extension: *.GIF image_codecs: Built-in EMF Codec, mime: image/x-emf, extension: *.EMF image_codecs: Built-in WMF Codec, mime: image/x-wmf, extension: *.WMF image_codecs: Built-in TIFF Codec, mime: image/tiff, extension: *.TIF;*.TIFF image_codecs: Built-in PNG Codec, mime: image/png, extension: *.PNG image_codecs: Built-in ICO Codec, mime: image/x-icon, extension: *.ICO Built-in PNG Codec, mime: image/png, extension: *.PNG
источник
Проще говоря, вы не можете. Причина в том, что Bitmap - это такой же тип изображения, как и JPEG, PNG и т. Д. После того, как вы загрузите изображение в Bitmap, вы получите изображение в формате bitmap. Невозможно взглянуть на растровое изображение и понять исходную кодировку изображения (даже если она отличается от Bitmap).
источник
Чтобы не беспокоиться о старой теме, но чтобы завершить это обсуждение, я хочу поделиться своим способом запроса всех форматов изображений, известных Windows.
using System.Diagnostics; using System.Drawing; using System.Drawing.Imaging; public static class ImageExtentions { public static ImageCodecInfo GetCodecInfo(this System.Drawing.Image img) { ImageCodecInfo[] decoders = ImageCodecInfo.GetImageDecoders(); foreach (ImageCodecInfo decoder in decoders) if (img.RawFormat.Guid == decoder.FormatID) return decoder; return null; } }
Теперь вы можете использовать его как расширение изображения, как показано ниже:
public void Test(Image img) { ImageCodecInfo info = img.GetCodecInfo(); if (info == null) Trace.TraceError("Image format is unkown"); else Trace.TraceInformation("Image format is " + info.FormatDescription); }
источник
Основываясь на работе Алекса выше (которую я фактически голосую как решение, поскольку это одна строка, но я еще не могу проголосовать, ха-ха), я придумал следующую функцию для библиотеки изображений. Требуется 4.0
Public Enum Formats Unknown Bmp Emf Wmf Gif Jpeg Png Tiff Icon End Enum Public Shared Function ImageFormat(ByVal Image As System.Drawing.Image) As Formats If Not System.Enum.TryParse(Of Formats)(System.Drawing.Imaging.ImageCodecInfo.GetImageDecoders().ToList().[Single](Function(ImageCodecInfo) ImageCodecInfo.FormatID = Image.RawFormat.Guid).FormatDescription, True, ImageFormat) Then Return Formats.Unknown End If End Function
источник
Пара чистых методов расширения по типу
Image
для определения этого, основанных на находке Алекса выше (ImageCodecInfo.GetImageDecoders()
).Это сильно оптимизировано после первого вызова, поскольку статический ImageCodecsDictionary сохраняется в памяти (но только после того, как он был использован один раз).
public static class ImageCodecInfoX { private static Dictionary<Guid, ImageCodecInfoFull> _imageCodecsDictionary; public static Dictionary<Guid, ImageCodecInfoFull> ImageCodecsDictionary { get { if (_imageCodecsDictionary == null) { _imageCodecsDictionary = ImageCodecInfo.GetImageDecoders() .Select(i => { var format = ImageFormats.Unknown; switch (i.FormatDescription.ToLower()) { case "jpeg": format = ImageFormats.Jpeg; break; case "png": format = ImageFormats.Png; break; case "icon": format = ImageFormats.Icon; break; case "gif": format = ImageFormats.Gif; break; case "bmp": format = ImageFormats.Bmp; break; case "tiff": format = ImageFormats.Tiff; break; case "emf": format = ImageFormats.Emf; break; case "wmf": format = ImageFormats.Wmf; break; } return new ImageCodecInfoFull(i) { Format = format }; }) .ToDictionary(c => c.CodecInfo.FormatID); } return _imageCodecsDictionary; } } public static ImageCodecInfoFull CodecInfo(this Image image) { ImageCodecInfoFull codecInfo = null; if (!ImageCodecsDictionary.TryGetValue(image.RawFormat.Guid, out codecInfo)) return null; return codecInfo; } public static ImageFormats Format(this Image image) { var codec = image.CodecInfo(); return codec == null ? ImageFormats.Unknown : codec.Format; } } public enum ImageFormats { Jpeg, Png, Icon, Gif, Bmp, Emf, Wmf, Tiff, Unknown } /// <summary> /// Couples ImageCodecInfo with an ImageFormats type. /// </summary> public class ImageCodecInfoFull { public ImageCodecInfoFull(ImageCodecInfo codecInfo = null) { Format = ImageFormats.Unknown; CodecInfo = codecInfo; } public ImageCodecInfo CodecInfo { get; set; } public ImageFormats Format { get; set; } }
источник
одна странная проблема, с которой я столкнулся, когда пытался получить тип mime с помощью imagecodeinfo ... для некоторых файлов png направляющие были не совсем такими же ...
сначала я проверял с помощью ImageCodecinfo, и если код не находит формат изображения, я сравнивал формат изображения, используя решение Маттиаса Вуттке.
если оба вышеупомянутых решения не сработали, тогда использовался метод расширения для получения типа файла mime ..
если тип mime изменяется, файл также изменяется, мы вычисляли контрольную сумму загруженных файлов, чтобы она соответствовала контрольной сумме исходного файла на сервере ... поэтому для нас было важно получить правильный файл в качестве вывода.
источник
Агент СК , мне понравился ваш метод расширения, я добавил перегрузку строки, плюс я сократил код для вашего метода:
public static class ImageExtentions { public static ImageCodecInfo GetCodecInfo(this Image img) => ImageCodecInfo.GetImageDecoders().FirstOrDefault(decoder => decoder.FormatID == img.RawFormat.Guid); // Note: this will throw an exception if "file" is not an Image file // quick fix is a try/catch, but there are more sophisticated methods public static ImageCodecInfo GetCodecInfo(this string file) { using (var img = Image.FromFile(file)) return img.GetCodecInfo(); } } // Usage: string file = @"C:\MyImage.tif"; string description = $"Image format is {file.GetCodecInfo()?.FormatDescription ?? "unknown"}."; Console.WriteLine(description);
источник
Чезаре Империали предложил самый простой метод :
var format = new ImageFormat(Image.FromFile(myFile).RawFormat.Guid);
Однако .ToString () для .jpg возвращает «[ImageFormat: b96b3cae-0728-11d3-9d7b-0000f81ef32e]» вместо «Jpeg». Если это важно для вас, вот мое решение:
public static class ImageFilesHelper { public static List<ImageFormat> ImageFormats => typeof(ImageFormat).GetProperties(BindingFlags.Static | BindingFlags.Public) .Select(p => (ImageFormat)p.GetValue(null, null)).ToList(); public static ImageFormat ImageFormatFromRawFormat(ImageFormat raw) => ImageFormats.FirstOrDefault(f => raw.Equals(f)) ?? ImageFormat.Bmp; } // usage: var format = ImageFilesHelper.ImageFormatFromRawFormat(Image.FromFile(myFile).RawFormat);
источник