【问题标题】:Convert Base64 String To Image Attachment将 Base64 字符串转换为图像附件
【发布时间】:2018-03-01 20:01:51
【问题描述】:

我有一个转换为 base64 字符串的图像,我需要将其转换回图像并附加到 MailMessage

这是将其从 base64 字符串转换为图像的相关代码(我想我可以跳过 Image 对象并使用一个内存流来执行此操作,但在实现时遇到了一些问题)。尝试将 Image 保存到 MemoryStream 会引发通用 GDI+ 错误:

Image image = ImageHelper.Base64ToImage(attachment.FieldData);

if (image != null)
{
    using (var ms = new MemoryStream())
    {
        image.Save(ms, ImageFormat.Png); // Throws a generic GDI+ error on Save

        ms.Position = 0;

        var imageAttachment = new Attachment(ms, "image.png", "image/png");

        message.Attachments.Add(imageAttachment);
    }
}

public static class ImageHelper
{
    public static Image Base64ToImage(string base64String)
    {
        if (string.IsNullOrEmpty(base64String))
        {
            return null;
        }

        byte[] imageBytes = Convert.FromBase64String(base64String);

        using (var ms = new MemoryStream(imageBytes, 0, imageBytes.Length))
        {
            ms.Write(imageBytes, 0, imageBytes.Length);

            Image image = Image.FromStream(ms, true);

            return image;
        }
    }
}

我可以使用 img 标签在其他地方提供原始 base64 字符串,它工作正常,所以我确信问题不在于 base64 字符串本身:

<img src="data:image/png;base64,<myBase64StringHere>" alt="My Image" width="500" />

我在将其转换回来时一定做错了,但我无法找出问题所在。感谢您对此的任何帮助!

【问题讨论】:

  • 你确定图片有“color management information embedded in the data stream”吗?也许您只想“验证图像”,在这种情况下使用 this overloadfalse 嵌入颜色:Image.FromStream(ms, false, true);
  • 我尝试了Image.FromStream(ms, false, true)Image.FromStream(ms),但在Image.Save(ms, ImageFormat.Png) 上仍然得到相同的A generic error occurred in GDI+. 错误
  • 认为我在阅读here 时发现了您的问题,您没有使用Bitmap,但Image.FromStream() 也会发生同样的事情:“您必须在图像的生命周期内保持流打开”。但是,您是using MemoryStream,因此在返回图像时将其处置,一旦发生这种情况,Image 将不再可用。也许你的静态类需要返回Tuple&lt;Image, MemoryStream&gt;
  • 确实是这个问题,非常感谢!如果您将此作为答案发布,我可以接受。

标签: c# asp.net-mvc base64 image-conversion


【解决方案1】:

Image.FromStream(Stream) 说,“您必须在 Image 的生命周期内保持流打开”,但您的 using 语句会在返回 Image 时处理流。一种解决方法是将图像和流作为元组一起返回,并且不带using

public static Tuple<Image, MemoryStream> Base64ToImage(string base64String)
{
    if (string.IsNullOrEmpty(base64String))
    {
        return null;
    }

    byte[] imageBytes = Convert.FromBase64String(base64String);
    var ms = new MemoryStream(imageBytes, 0, imageBytes.Length)        
    ms.Write(imageBytes, 0, imageBytes.Length);
    Image image = Image.FromStream(ms, true);

    return new Tuple<Image, MemoryStream>(image, ms);
}

还要注意注意并查看 MSDN 页面上的每个重载。通常我会说,“查看最全面的重载以获取所有评论和注释”,但在这种情况下,这是不正确的。最大过载的 MSDN 页面Image.FromStream Method (Stream, Boolean, Boolean) 确实没有提到您需要保持流打开,但我相当肯定这是该特定页面上的错误。

【讨论】:

    猜你喜欢
    • 2018-09-07
    • 2014-07-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-01-07
    • 2014-09-14
    • 2013-02-15
    相关资源
    最近更新 更多