在C#中使用Bitmap对象查找图像格式
我加载图像文件硬盘驱动器的二进制字节并将其加载到一个Bitmap对象。 如何从Bitmap对象中find图像types[JPEG,PNG,BMP等]?
看起来微不足道 但是,想不出来!
有其他的方法吗?
感谢您的回应。
更新的正确解决scheme:
@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; } }
如果您想知道图像的格式,可以使用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
<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");
debugging输出:
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等的图像types。 一旦你把一个图像加载到一个位图的位图格式的图像。 没有办法看一个位图,并了解图像的原始编码(如果它甚至不同于位图)。
基于亚历克斯的上述工作(我实际上投票作为解决scheme,因为它是一条线 – 但我不能投票哈哈),我想出了一个图像库的以下function。 它需要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
基于上面的Alex( ImageCodecInfo.GetImageDecoders()
)的查找来确定这个Image
types的一些干净的扩展方法。
这是第一次调用后高度优化,因为静态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; } }
一个奇怪的问题,当我正在尝试使用imagecodeinfo获取MIMEtypes..对于一些PNG文件GUID不完全相同…
首先我要检查ImageCodecinfo,如果代码没有find图像格式,那么我使用Matthias Wuttke的解决scheme比较图像格式。
如果上述解决scheme都失败,则使用扩展方法获取文件MIMEtypes..
如果MIMEtypes改变,那么文件也会改变,我们正在计算下载的文件校验和,以与服务器上的原始文件的校验和相匹配。所以对于我们来说,获取适当的文件作为输出是重要的。
不要去打扰老话题,但要完成这个讨论,我想分享我的方式来查询所有的图像格式,由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); }