62

I am trying to convert a Base64String to an image which needs to be saved locally.

At the moment, my code is able to save the image but when I open the saved image, it says "Invalid Image".

enter image description here

Code:

try
{
    using (var imageFile = new StreamWriter(filePath))
    {
        imageFile.Write(resizeImage.Content);
        imageFile.Close();
    }
}

The Content is a string object which contains the Base64 String.

Subby
  • 5,370
  • 15
  • 70
  • 125
  • 2
    You can use `Convert.FromBase64String` to get a byte array. Then from there you load that into a `MemoryStream` or use the array as input to an `Image` or you can write out to a `File`. but providing the code you have already will help immensely. – Paul Farry Sep 16 '13 at 11:44
  • There's multiple things wrong that I can see. Firstly, you're not writing a binary file.. You also don't appear to be decoding the base64 anywhere.. – Simon Whitehead Sep 16 '13 at 11:44
  • Ahah thank you. I'll shall give that a try. – Subby Sep 16 '13 at 11:46
  • @ByteBlast - Sorry I thought I had pasted the code in but I hadn't and published the question. – Subby Sep 16 '13 at 11:49

4 Answers4

107

First, convert the base 64 string to an Image, then use the Image.Save method.

To convert from base 64 string to Image:

 public Image Base64ToImage(string base64String)
 {
    // Convert base 64 string to byte[]
    byte[] imageBytes = Convert.FromBase64String(base64String);
    // Convert byte[] to Image
    using (var ms = new MemoryStream(imageBytes, 0, imageBytes.Length))
    {
        Image image = Image.FromStream(ms, true);
        return image;
    }
 }

To convert from Image to base 64 string:

public string ImageToBase64(Image image,System.Drawing.Imaging.ImageFormat format)
{
  using (MemoryStream ms = new MemoryStream())
  {
    // Convert Image to byte[]
    image.Save(ms, format);
    byte[] imageBytes = ms.ToArray();

    // Convert byte[] to base 64 string
    string base64String = Convert.ToBase64String(imageBytes);
    return base64String;
  }
}

Finally, you can easily to call Image.Save(filePath); to save the image.

johnnyRose
  • 7,310
  • 17
  • 40
  • 61
Monah
  • 6,714
  • 6
  • 22
  • 52
  • you are more than welcome, please mark the reply as answer if it solved your problem, you too :) – Monah Sep 16 '13 at 11:54
  • 2
    +1 for the reverse solution. I was looking for that. :-) – shashwat Mar 07 '14 at 10:02
  • 1
    Isn't ms.Write(imageBytes, 0, imageBytes.Length) redundant here? Seems like MemoryStream ms = new MemoryStream(imageBytes) will create MemoryStream and initialize it with imageBytes, so Write() is not needed. – Crulex Mar 25 '15 at 12:35
  • thank you for the hint, that code when I answered was without testing, I will add note in the answer. – Monah Mar 25 '15 at 12:57
  • @HadiHassan Your memorystream should be wrapped in a using – Jose Luis Apr 17 '15 at 08:26
  • Any idea on this question? http://stackoverflow.com/questions/30751449/save-taskstring-type-to-string-giving-catastrophic-failure?noredirect=1#comment49559004_30751449 – yalematta Jun 10 '15 at 12:33
  • iam getting a error like ..system.windows.Controls.Image does not contain a definition for "FromStream"..... please help.. – Kartiikeya Jun 16 '15 at 09:24
  • @Kartiikeya Image belongs to "System.Drawing" and not system.windows.controls – Monah Jun 16 '15 at 10:34
  • Why not closing `MemoryStream` in `Base64ToImage`? – Andy Jun 29 '15 at 10:15
  • @Andy according to Microsoft, the using statement automatically closes the stream and calls dispose on the object when the code that is using it has completed. you can see this reference: https://msdn.microsoft.com/en-us/library/system.idisposable.dispose.aspx – Monah Jun 30 '15 at 07:18
  • @HadiHassan in `ImageToBase64` I totally agree. But in `Base64ToImage` I don't see a `using` or a `Close()`. – Andy Jun 30 '15 at 07:26
  • @Andy i edited the answer to include the using statement, thank you for the tip – Monah Jun 30 '15 at 10:30
  • using visual studio community 2015, windows 10, Image appear to not be a class of System.Drawing? – pgee70 Sep 25 '15 at 05:39
95

So with the code you have provided.

var bytes = Convert.FromBase64String(resizeImage.Content);
using (var imageFile = new FileStream(filePath, FileMode.Create))
{
    imageFile.Write(bytes ,0, bytes.Length);
    imageFile.Flush();
}
Paul Farry
  • 4,730
  • 2
  • 35
  • 61
  • 1
    Thank you Paul. That worked wonders. I now understand that I had to convert/decode the string. – Subby Sep 16 '13 at 11:52
  • Thanks, this was working for me to convert the contentBytes string of a attachment json reply from the Microsoft graph. Now I can save my atttachments to real files. – bert Sep 19 '17 at 09:08
8
public Image Base64ToImage(string base64String)
{
   // Convert Base64 String to byte[]
    byte[] imageBytes = Convert.FromBase64String(base64String);
    MemoryStream ms = new MemoryStream(imageBytes, 0, imageBytes.Length);

    // Convert byte[] to Image
    ms.Write(imageBytes, 0, imageBytes.Length);
    Image image = Image.FromStream(ms, true);

    return image;
}
MethodMan
  • 18,625
  • 6
  • 34
  • 52
0

Front :

  <Image Name="camImage"/>

Back:

 public async void Base64ToImage(string base64String)
        {
            // read stream
            var bytes = Convert.FromBase64String(base64String);
            var image = bytes.AsBuffer().AsStream().AsRandomAccessStream();

            // decode image
            var decoder = await BitmapDecoder.CreateAsync(image);
            image.Seek(0);

            // create bitmap
            var output = new WriteableBitmap((int)decoder.PixelHeight, (int)decoder.PixelWidth);
            await output.SetSourceAsync(image);

            camImage.Source = output;
        }