【问题标题】:Get ImageFormat from System.Drawing.Image.RawFormat从 System.Drawing.Image.RawFormat 获取 ImageFormat
【发布时间】:2011-05-16 06:15:22
【问题描述】:

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

我得到了例外:

一个值不能为空。参数名称:编码器"

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

如果我直接传入 ImageFormat 对象,它会起作用,例如ImageFormat.Jpeg.

rawformat 转换为ImageFormat 的最佳方法是什么(最好不要使用switch 语句或大量if 语句)

谢谢 本

【问题讨论】:

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


    【解决方案1】:

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

    【讨论】:

    • 虽然这不是问题的答案,但它是避免大型 switch/if 语句的一种非常好的方法。
    • 也为我工作!我将它翻译成 VB.NET 来完成一个简单的图像大小调整任务。我会添加它作为答案,以防万一有人想要它。
    【解决方案2】:

    抱歉,我发现无法从解析或生成的 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 成员数组来整理它,但我认为您将无法避免切换或循环。

    最好的问候,马蒂亚斯

    【讨论】:

      【解决方案3】:

      你在找这个吗?

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

      【讨论】:

        【解决方案4】:

        还有一种方法可以将其RawFormat 中的Image 保存为一些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();
            }
        }
        

        【讨论】:

          【解决方案5】:

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

          【讨论】:

            【解决方案6】:

            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
            

            【讨论】:

              【解决方案7】:

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

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

              如果上面提到的两个解决方案都失败了,那么使用扩展方法来获取文件 mime 类型..

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

              【讨论】:

                【解决方案8】:

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

                var formatDescription = ImageCodecInfo.GetImageDecoders().FirstOrDefault(w => w.FormatID == image.RawFormat.Guid)?.FormatDescription;
                
                filePath = Path.ChangeExtension(filePath, formatDescription);
                
                image.Save(filePath);
                

                【讨论】:

                  猜你喜欢
                  • 2010-11-23
                  • 1970-01-01
                  • 2013-12-12
                  • 1970-01-01
                  • 2011-05-09
                  • 2011-10-20
                  • 1970-01-01
                  • 2014-11-15
                  • 1970-01-01
                  相关资源
                  最近更新 更多