2016-10-24 12 views
0

У меня есть изображение, преобразованное в строку base64, которое мне нужно преобразовать обратно в изображение и прикрепить к MailMessage.Convert Base64 String To Image Attachment

Вот соответствующий код, преобразующий его из строки 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; 
     } 
    } 
} 

Я в состоянии обслуживать необработанный строку base64 в другом месте, используя IMG тег, и он работает нормально, так что я уверен, что проблема ISN «т с самой base64 строки:

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

я должен делать что-то неправильно в преобразовании его обратно, но я не был в состоянии выяснить этот вопрос. Спасибо за любую помощь!

+0

Уверен, что изображение имеет «информация о управлении цветом в встроенном потоке данных» (https://msdn.microsoft.com/en-us/library/1kcb3wy4 (v = vs.110) .aspx) "? Возможно, вы только хотели «проверить изображение», и в этом случае используйте [эту перегрузку] (https://msdn.microsoft.com/en-us/library/21zw9ah6 (v = vs.110) .aspx) с 'false 'для встроенного материала цвета:' Image.FromStream (ms, false, true); '. – Quantic

+0

Я попробовал как «Image.FromStream (ms, false, true)», так и «Image.FromStream (ms)», но все равно получаю то же самое »Общая ошибка, произошедшая в ошибке GDI + .' на' Image.Save (ms, ImageFormat .Png) ' –

+1

Думаю, я нашел вашу проблему от чтения [здесь] (http://stackoverflow.com/questions/336387/image-save-throws-a-gdi-exception-because-the-memory-stream-is- закрыто), вы не используете 'Bitmap', но то же самое происходит с [' Image.FromStream() '] (https://msdn.microsoft.com/en-us/library/93z9ee4x (v = vs.110) .aspx): «Вы должны держать поток открытым для жизни изображения». Тем не менее, вы используете «Memory», чтобы он отображался, когда изображение возвращается, и как только это произойдет, «Image» больше не используется. Возможно, ваш статический класс должен вернуть 'Tuple '. – Quantic

ответ

2

Image.FromStream(Stream) говорит: «Вы должны держать поток открытым для жизни изображения», но ваш оператор using предоставляет поток при возврате изображения. Обходной бы вернуть как изображение и поток вместе в виде кортежа и без 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) делает не упоминает, что вам нужно держать поток открытым, но я уверен, что это ошибка на этой конкретной странице.