Найти формат изображения с помощью объекта Bitmap в C #
Я загружаю двоичные байты жесткого диска файла изображения и загружаю его в объект Bitmap. Как найти тип изображения [JPEG, PNG, BMP и т. Д.] Из объекта Bitmap?
Выглядит тривиально. Но, не мог понять это!
Есть ли альтернативный подход?
- Android: загружено изображение Picasso. как показать сообщение об ошибке
- Как реализовать галерею изображений в Gridview в Android?
- Как повернуть изображение в WinForms
- Как преобразовать координаты изображения в координаты растрового изображения?
- Поворот изображения canvasа HTML5
Цените свой ответ.
ОБНОВЛЕНО ПРАВИЛЬНОЕ РЕШЕНИЕ:
@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; } }
- Изображение SVG не работает в Firefox
- Как захватить UIView в UIImage без потери качества на дисплее сетчатки
- Сохранение изображений: файлы или капли?
- Графики Matplotlib теряют прозрачность при сохранении как .ps / .eps
- Измените цвет текста одного ClickableSpan при нажатии, не затрагивая другие ClickableSpans в том же TextView
- Java: rotation изображений
- Как кодировать серию изображений в H264 с использованием API x264 C?
- WPF - импортировать изображение в качестве ресурса
Если вы хотите узнать формат изображения, вы можете загрузить файл с помощью classа Image и проверить его свойство RawFormat :
using(Image img = Image.FromFile(@"C:\path\to\img.jpg")) { if (img.RawFormat.Equals(System.Drawing.Imaging.ImageFormat.Jpeg)) { // ... } }
Вот мой метод расширения. Надеюсь, это поможет кому-то.
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
код:
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).
Основываясь на работе Алекса выше (которую я фактически голосую как решение, так как это одна строка, но я не могу проголосовать еще ха-ха), я придумал следующую функцию для библиотеки изображений. Он требует 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
Чтобы не беспокоиться по старой теме, но для завершения этого обсуждения, я хочу поделиться своим путем, чтобы запросить все форматы изображений, известные 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); }
Несколько простых методов расширения для типа Image
для определения этого, основываясь на ImageCodecInfo.GetImageDecoders()
выше Alex ( ImageCodecInfo.GetImageDecoders()
).
Это очень оптимизировано после первого вызова, поскольку статический ImageCodecsDictionary сохраняется в памяти (но только после того, как он был использован один раз).
public static class ImageCodecInfoX { private static Dictionary _imageCodecsDictionary; public static Dictionary 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 } /// /// Couples ImageCodecInfo with an ImageFormats type. /// 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, и если код не нашел образ, тогда я сравнил изображение с помощью решения Matthias Wuttke.
если оба вышеупомянутых решения не сработали, то используется метод расширения для получения типа файла mime.
если тип mime изменяется, то файл также изменяется, мы вычисляем контрольную сумму загруженных файлов, чтобы соответствовать контрольной сумме исходного файла на сервере .. так что для нас было важно получить правильный файл в качестве вывода.
Агент CK , мне понравился ваш метод расширения и добавлена перегрузка строк, а также я уменьшил код для вашего метода:
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 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);