2016-10-24 7 views
0

Ich habe ein Bild in eine Base64-Zeichenfolge konvertiert, die ich zurück zu einem Bild konvertieren und an eine MailMessage anhängen muss.Convert Base64 String in Bild Anhang

Hier ist der relevante Code konvertiert es von Base64 String zu Bild (ich denke, ich kann das Image-Objekt überspringen und dies mit einem Speicher-Stream tun, hatte aber einige Probleme bei der Umsetzung). die Image zu einem MemoryStream wirft einen generischen GDI + Fehler speichern Den Versuch:

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

Ich bin in der Lage, das rohe Base64-String an anderer Stelle mit einem img-Tag zu dienen und es funktioniert gut, also bin ich zuversichtlich, dass das Problem isn ‚t mit dem base64 String selbst:

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

ich es etwas falsch machen bei der Umwandlung zurück sein müssen, aber ich habe es nicht gelungen, das Problem herauszufinden. Danke für jede Hilfe dabei!

+0

Sind Sie sicher, dass das Bild "[' Farbmanagement-Informationen in den Datenstrom eingebettet '] (https://msdn.microsoft.com/en-us/library/1kcb3wy4 (v = vs.110) .aspx) hat) "? Vielleicht wollten Sie nur "das Bild validieren", in diesem Fall verwenden Sie [diese Überladung] (https://msdn.microsoft.com/en-us/library/21zw9ah6 (v = vs.110) .aspx) mit 'false 'für die eingebettete Farbe:' Image.FromStream (ms, false, true); '. – Quantic

+0

Ich habe versucht sowohl 'Image.FromStream (ms, falsch, wahr)' und 'Image.FromStream (ms)', aber immer noch das gleiche 'Ein generischer Fehler aufgetreten in GDI + .' Fehler auf' Image.Save (ms, ImageFormat .Png) ' –

+1

Denke, ich habe dein Problem beim Lesen gefunden [hier] (http://stackoverflow.com/questions/336387/image-save-throws-a-gdi-exception-because-the-memory-stream-is- geschlossen), Sie verwenden nicht "Bitmap", aber das Gleiche passiert mit ['Image.FromStream()'] (https://msdn.microsoft.com/en-us/library/93z9ee4x (v = vs.110) .aspx): "Sie müssen den Stream für die Lebensdauer des Bildes offen halten". Sie verwenden den MemoryStream jedoch so, dass er bei der Rückgabe des Bildes entsorgt wird. Sobald dies geschieht, ist das Image nicht mehr verwendbar. Vielleicht muss Ihre statische Klasse 'Tuple ' zurückgeben. – Quantic

Antwort

2

Image.FromStream(Stream) sagt, "Sie müssen den Stream für die Lebensdauer des Bildes geöffnet halten", aber Ihre using Anweisung verfügt über den Stream, wie das Bild zurückgegeben wird. Eine Abhilfe wäre sowohl das Bild und den Strom zurückzukehren zusammen als ein Tupel und ohne 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); 
} 

auch darauf achten, beachten und jede Überlastung auf den MSDN-Seiten anzuzeigen. Normalerweise würde ich sagen: "Sehen Sie die umfassendste Überladung, um alle Bemerkungen und Notizen zu erhalten", aber in diesem Fall ist das nicht wahr. Die MSDN-Seite für die größte Überladung, Image.FromStream Method (Stream, Boolean, Boolean) tut nicht Erwähnung, dass Sie den Stream geöffnet halten müssen, aber ich bin ziemlich sicher, dass ein Fehler auf dieser bestimmten Seite ist.