Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/280.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在C中使用位图对象查找图像格式#_C#_.net_Image - Fatal编程技术网

C# 在C中使用位图对象查找图像格式#

C# 在C中使用位图对象查找图像格式#,c#,.net,image,C#,.net,Image,我正在加载图像文件硬盘的二进制字节,并将其加载到位图对象中。如何从位图对象中找到图像类型[JPEG、PNG、BMP等] 看起来微不足道。但是,我想不出来 有没有其他办法 感谢您的回复 更新了正确的解决方案: @谢谢你的正确回复 实现这一点的示例代码 using (MemoryStream imageMemStream = new MemoryStream(fileData)) { using (Bitmap bitmap = new Bitmap(imageMemStream))

我正在加载图像文件硬盘的二进制字节,并将其加载到位图对象中。如何从位图对象中找到图像类型[JPEG、PNG、BMP等]

看起来微不足道。但是,我想不出来

有没有其他办法

感谢您的回复

更新了正确的解决方案:

@谢谢你的正确回复

实现这一点的示例代码

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;
    }
}

简单地说,你不能。原因是位图是一种图像类型,其方式与JPEG、PNG等相同。一旦将图像加载到位图中,将显示位图格式的图像。无法查看位图并理解图像的原始编码(如果它甚至与位图不同)

如果您想知道图像的格式,可以使用类加载文件,并检查其属性:

using(Image img = Image.FromFile(@"C:\path\to\img.jpg"))
{
    if (img.RawFormat.Equals(System.Drawing.Imaging.ImageFormat.Jpeg))
    {
      // ...
    }
}

你当然可以<代码>图像格式意义不大
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>

调试输出:

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

这是我的扩展方法。希望这能帮助别人

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;            
    }

基于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

这是我的代码。您必须首先将完整的映像或标头(前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;
}

基于上面Alex的发现(
ImageCodeInfo.GetImageDecoders()
),在type
Image
上有两个干净的扩展方法来确定这一点

这在第一次调用后得到了高度优化,因为静态ImageCodecsDictionary保存在内存中(但仅在使用一次之后)

公共静态类ImageCodeInfox
{
私有静态字典_imagecodesdictionary;
公共静态字典ImageCodecsDictionary
{
得到
{
if(_imagecodesdictionary==null){
_图像编解码器=
ImageCodecInfo.GetImageDecoders()
.选择(i=>{
var format=图像格式。未知;
开关(i.FormatDescription.ToLower()){
案例“jpeg”:format=ImageFormats.jpeg;break;
案例“png”:format=ImageFormats.png;break;
案例“图标”:格式=图像格式。图标;中断;
案例“gif”:format=ImageFormats.gif;中断;
大小写“bmp”:format=ImageFormats.bmp;break;
案例“tiff”:format=ImageFormats.tiff;break;
案例“emf”:format=ImageFormats.emf;break;
案例“wmf”:format=ImageFormats.wmf;break;
}
返回新的ImageCodeInfoFull(i){Format=Format};
})
.ToDictionary(c=>c.CodecInfo.FormatID);
}
返回_imagecodesdictionary;
}
}
公共静态图像codecinfofull CodecInfo(此图像)
{
ImageCodecInfoFull codecInfo=null;
if(!imagecodesdictionary.TryGetValue(image.RawFormat.Guid,out codecInfo))
返回null;
返回编码信息;
}
公共静态图像格式(此图像)
{
var codec=image.CodecInfo();
返回codec==null?ImageFormats。未知:codec.Format;
}
}
公共枚举图像格式{Jpeg、Png、图标、Gif、Bmp、Emf、Wmf、Tiff、未知}
/// 
///将ImageCodecInfo与ImageFormats类型耦合。
/// 
公共类ImageCodecInfoFull
{
公共IMAGECODECINFOULL(ImageCodecInfo codecInfo=null)
{
格式=图像格式。未知;
CodecInfo=CodecInfo;
}
公共图像编码信息编码信息{get;set;}
公共图像格式格式{get;set;}
}

当我试图使用imagecodeinfo获取mime类型时,遇到了一个奇怪的问题。。对于某些png文件,GUID不完全相同

首先我检查ImageCodeInfo,如果代码没有找到imageformat,那么我使用Matthias Wuttke的解决方案比较imageformat

如果上述两种解决方案均失败,则使用扩展名方法获取文件mime类型


如果mime类型更改,那么文件也会更改,我们正在计算下载的文件校验和,以与服务器上原始文件的校验和匹配。。因此,对于我们来说,获得适当的文件作为输出是非常重要的。

不必费心讨论老话题,但为了完成本次讨论,我想与大家分享我查询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);
}

最简单的方法如下所示:

但是,.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);
公共静态类ImageFileHelper
{
公共静态列表ImageFormats=>
typeof(ImageFormat).GetProperties(BindingFlags.Static | BindingFlags.Public)
.Select(p=>(ImageFormat)p.GetValue(null,null)).ToList();
公共静态ImageFormat ImageFormatFromRawFormat(ImageFormat raw)=>
ImageFormats.FirstOrDefault(f=>raw.Equals(f))??ImageFormat.Bmp;
}
//用法:
var format=ImageFileHelper.ImageFormatFromRawFormat(Image.FromFile(myFile).RawFormat);
,我喜欢您的扩展方法,并添加了一个字符串重载,另外我还减少了您方法的代码:

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);

您可以将
System.Drawing.Imaging
命名空间添加到您的using指令中,以使格式检查不那么冗长…@CMS:同意!想要显示其他信息的完整命名空间。Hmmm。。。我试过同样的方法,但不起作用。我加载了一个PNG,当我比较它的
var format = new ImageFormat(Image.FromFile(myFile).RawFormat.Guid);
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);
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);