从System.Drawing.Image.RawFormat获取ImageFormat

时间:2010-11-26 15:50:17

标签: c# system.drawing system.drawing.imaging

尝试呼叫Image.Save(MemoryStream, ImageFormat)时,此代码失败。

我得到例外:

  

a值不能为null。参数名称:encoder“

ImageFormat format = generatedImage.RawFormat as ImageFormat;
image.ImageData = generatedImage.Save(format);

如果我直接传入ImageFormat个对象就行了ImageFormat.Jpeg

rawformat转换为ImageFormat的最佳方法是什么(理想情况下,没有switch语句或许多if语句)

由于 本

8 个答案:

答案 0 :(得分:16)

我使用以下的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";
}

答案 1 :(得分:9)

对不起,我发现没有可能直接从解析或生成的Image对象中提取“正确的”ImageFormat。

这是我的代码,您可以通过存储静态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成员来整理它,但我认为你将无法避免切换或循环。

最好的问候,马蒂亚斯

答案 2 :(得分:6)

你正在寻找这个吗?


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

答案 3 :(得分:1)

还可以将Image中的RawFormat保存到某些Stream。见http://bytes.com/topic/c-sharp/answers/944402-how-access-raw-image-data-resource-file#post3733044

对我来说,效果如下:

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

答案 4 :(得分:0)

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

答案 5 :(得分:0)

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

首先我正在使用ImageCodecinfo进行检查,如果代码找不到图像格式,那么我使用Matthias Wuttke的解决方案对图像格式进行了比较。

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

如果mime类型改变,那么文件也会改变,我们计算下载的文件校验和以匹配服务器上原始文件的校验和..所以对我们来说,获取正确的文件作为输出是重要的。

答案 6 :(得分:0)

Cesare Imperiali上面的答案在我的测试中有效。唯一的缺点(如果重要的是)Jpeg的.ToString()返回“[ImageFormat:b96b3cae-0728-11d3-9d7b-0000f81ef32e]”而不是“Jpeg”。

如果这对您很重要,那么您可以通过以下方式获得具有较少代码的精确静态ImageFormat:

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

答案 7 :(得分:0)

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

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

filePath = Path.ChangeExtension(filePath, formatDescription);

image.Save(filePath);