在 C# 中使用 Bitmap 对象查找图像格式
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1397512/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Find image format using Bitmap object in C#
提问by pencilslate
I am loading the binary bytes of the image file hard drive and loading it into a Bitmap object. How do i find the image type[JPEG, PNG, BMP etc] from the Bitmap object?
我正在加载图像文件硬盘驱动器的二进制字节并将其加载到位图对象中。如何从 Bitmap 对象中找到图像类型 [JPEG、PNG、BMP 等]?
Looks trivial. But, couldn't figure it out!
看起来微不足道。但是,想不通!
Is there an alternative approach?
有没有替代方法?
Appreciate your response.
感谢您的回复。
UPDATED CORRECT SOLUTION:
更新的正确解决方案:
@CMS: Thanks for the correct response!
@CMS:感谢您的正确回复!
Sample code to achieve this.
实现此目的的示例代码。
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;
}
}
采纳答案by CMS
If you want to know the format of an image, you can load the file with the Imageclass, and check its RawFormatproperty:
如果您想知道图像的格式,可以使用Image类加载文件,并检查其RawFormat属性:
using(Image img = Image.FromFile(@"C:\path\to\img.jpg"))
{
if (img.RawFormat.Equals(System.Drawing.Imaging.ImageFormat.Jpeg))
{
// ...
}
}
回答by JaredPar
Simply speaking you can't. The reason why is that Bitmap is a type of image in the same way that JPEG, PNG, etc are. Once you load a image into a Bitmap the image of the bitmap format. There is no way to look at a bitmap and understand the original encoding of the image (if it's even different than Bitmap).
简单地说,你不能。原因是 Bitmap 是一种与 JPEG、PNG 等相同的图像类型。将图像加载到位图后,位图格式的图像。没有办法查看位图并了解图像的原始编码(如果它甚至与位图不同)。
回答by Alex
of course you can. ImageFormat
doesn't mean much. ImageCodecInfo
has much more meaning.
当然可以。ImageFormat
没有多大意义。ImageCodecInfo
有更多的意义。
red_dot.png
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>
code:
代码:
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");
debug output:
调试输出:
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
回答by sebacipo
Here is my extension method. Hope this help someone.
这是我的扩展方法。希望这有助于某人。
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;
}
回答by toddmo
Based on Alex's work above (which I actually vote as the solution, since it's one line - but I can't vote yet haha), I came up with the following function for an image library. It requires 4.0
基于 Alex 在上面的工作(我实际上投票作为解决方案,因为它是一行 - 但我还不能投票哈哈),我想出了以下图像库函数。它需要 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
回答by Alex
here is my code for this. You have to load the complete image or the header (first 4 bytes) to a byte array first.
这是我的代码。您必须首先将完整图像或标题(前 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;
}
回答by Nicholas Petersen
A couple of clean extension methods on type Image
for determining this, based on the find by Alex above (ImageCodecInfo.GetImageDecoders()
).
Image
确定这一点的几个干净的类型扩展方法,基于上面 Alex 的发现 ( ImageCodecInfo.GetImageDecoders()
)。
This is highly optimized after the first call, as the static ImageCodecsDictionary is saved in memory (but only after it has been used once).
这是在第一次调用后高度优化的,因为静态 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; }
}
回答by Samuel Joy
one weird problem i faced when i was trying to get the mime type using imagecodeinfo.. for some png files the guids were not exactly same...
当我尝试使用 imagecodeinfo 获取 mime 类型时遇到的一个奇怪问题..对于某些 png 文件,guids 不完全相同...
first i was checking with the ImageCodecinfo and if code does not find the imageformat then i compared the imageformat using Matthias Wuttke's solution.
首先,我正在检查 ImageCodecinfo,如果代码没有找到图像格式,那么我使用 Matthias Wuttke 的解决方案比较了图像格式。
if both the above mentioned solution failed then used the extension method to get the file mime type..
如果上面提到的解决方案都失败了,那么使用扩展方法来获取文件 mime 类型..
if the mime type changes then the file also changes, we were calculating the downloaded files checksum to match with the checksum of the original file on the server .. so for us it was importent to get proper file as output.
如果 mime 类型发生变化,那么文件也会发生变化,我们正在计算下载的文件校验和以与服务器上原始文件的校验和相匹配..所以对我们来说,获得正确的文件作为输出很重要。
回答by Agent CK
Not to bother to on old topic, but to complete this discussion, I want to share my way to query allimage formats, known by windows.
不打扰老话题,但为了完成这个讨论,我想分享我查询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;
}
}
Now you can use it as an an image extension as shown below:
现在您可以将其用作图像扩展,如下所示:
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);
}
回答by JohnnyIV
The simplest method was offered by Cesare Imperialias this:
Cesare Imperiali提供了最简单的方法,如下所示:
var format = new ImageFormat(Image.FromFile(myFile).RawFormat.Guid);
However, the .ToString() for a .jpg returns "[ImageFormat: b96b3cae-0728-11d3-9d7b-0000f81ef32e]" instead of "Jpeg". If that matters to you, here is my solution:
但是,.jpg 的 .ToString() 返回“[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);