C# 从System.Drawing.Image.RawFormat获取ImageFormat

C# 从System.Drawing.Image.RawFormat获取ImageFormat,c#,system.drawing,system.drawing.imaging,C#,System.drawing,System.drawing.imaging,尝试调用Image.Save(MemoryStream,ImageFormat)时,此代码失败 我得到一个例外: 值不能为null。参数名称:编码器“ ImageFormat format=generateImage.RawFormat作为ImageFormat; image.ImageData=generatedImage.Save(格式); 如果我直接传入ImageFormat对象,例如ImageFormat.Jpeg,它就可以工作 将rawformat转换为ImageFormat的最佳方

尝试调用
Image.Save(MemoryStream,ImageFormat)
时,此代码失败

我得到一个例外:

值不能为null。参数名称:编码器“

ImageFormat format=generateImage.RawFormat作为ImageFormat;
image.ImageData=generatedImage.Save(格式);
如果我直接传入
ImageFormat
对象,例如
ImageFormat.Jpeg
,它就可以工作

rawformat
转换为
ImageFormat
的最佳方式是什么(理想情况下不使用switch语句或大量if语句)

谢谢
Ben

很抱歉,我发现无法从解析或生成的图像对象中直接提取“正确”的图像格式

这是我的代码,您可以通过存储静态ImageFormat成员而不是mimetype来采用它

                if (image.RawFormat.Equals(ImageFormat.Jpeg))
                    binary.MetaInfo.Mimetype = "image/jpeg";
                else if (image.RawFormat.Equals(ImageFormat.Bmp))
                    binary.MetaInfo.Mimetype = "image/bmp";
                else if (image.RawFormat.Equals(ImageFormat.Emf))
                    binary.MetaInfo.Mimetype = "image/emf";
                else if (image.RawFormat.Equals(ImageFormat.Exif))
                    binary.MetaInfo.Mimetype = "image/exif";
                else if (image.RawFormat.Equals(ImageFormat.Gif))
                    binary.MetaInfo.Mimetype = "image/gif";
                else if (image.RawFormat.Equals(ImageFormat.Icon))
                    binary.MetaInfo.Mimetype = "image/icon";
                else if (image.RawFormat.Equals(ImageFormat.Png))
                    binary.MetaInfo.Mimetype = "image/png";
                else if (image.RawFormat.Equals(ImageFormat.Tiff))
                    binary.MetaInfo.Mimetype = "image/tiff";
                else if (image.RawFormat.Equals(ImageFormat.Wmf))
                    binary.MetaInfo.Mimetype = "image/wmf";
您可以使用静态ImageFormat成员数组来整理它,但我认为您将无法避免切换或循环


最好的问候,Matthias

我使用以下hepler方法进行同样的测试:

public static string GetMimeType(Image i)
{
    var imgguid = i.RawFormat.Guid;
    foreach (ImageCodecInfo codec in ImageCodecInfo.GetImageDecoders()) 
    {
        if (codec.FormatID == imgguid)
            return codec.MimeType;
    }
    return "image/unknown";
}

你在找这个吗


System.Drawing.Imaging.ImageFormat fmt = new System.Drawing.Imaging.ImageFormat(generatedImage.RawFormat.Guid);

还有一种方法可以将
图像
原始格式
保存到一些
。请参阅

对我来说,它的工作原理如下:

byte[] GetRawImageData(Image img)
{
    using(MemoryStream ms = new MemoryStream())
    {
        img.Save(ms, img.RawFormat);
        return ms.ToArray();
    }
}

Cheburek答案的VB.NET翻译:

Private Function GetMimeType(i As Drawing.Image) As String
    Dim imgguid As Guid = i.RawFormat.Guid
    For Each codec As ImageCodecInfo In ImageCodecInfo.GetImageDecoders()
        If (codec.FormatID = imgguid) Then
            Return codec.MimeType
        End If
    Next
    Return "image/unknown"
End Function

我尝试了Cheburek比较guid的方法。但是对于一些png图像,guid不匹配。因此我必须编写一个逻辑,它将使用Matthias Wuttke的解决方案和Cheburek的解决方案中提到的方法

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

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

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

以上的回答在我的测试中起了作用。唯一的缺点(如果有关系的话)是Jpeg的.ToString()返回“[图像格式: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);

从RawFormat中查找图像扩展并保存的全新、现代且通用的答案如下:

var formatDescription = ImageCodecInfo.GetImageDecoders().FirstOrDefault(w => w.FormatID == image.RawFormat.Guid)?.FormatDescription;

filePath = Path.ChangeExtension(filePath, formatDescription);

image.Save(filePath);

虽然这不是问题的答案,但这是避免使用大型switch/if语句的一种非常好的方法。对我来说也很有用!我将其翻译到VB.NET以完成一个简单的图像大小调整任务。我将添加它作为答案,以防有人需要它。