converting a base 64 string to an image and saving it
Asked Answered
W

12

174

Here is my code:

protected void SaveMyImage_Click(object sender, EventArgs e)
        {
            string imageUrl = Hidden1.Value;
            string saveLocation = Server.MapPath("~/PictureUploads/whatever2.png") ; 


            HttpWebRequest imageRequest = (HttpWebRequest)WebRequest.Create(imageUrl);
            WebResponse imageResponse = imageRequest.GetResponse();

            Stream responseStream = imageResponse.GetResponseStream();

            using (BinaryReader br = new BinaryReader(responseStream))
            {
                imageBytes = br.ReadBytes(500000);
                br.Close();
            }
            responseStream.Close();
            imageResponse.Close();

            FileStream fs = new FileStream(saveLocation, FileMode.Create);
            BinaryWriter bw = new BinaryWriter(fs);
            try
            {
                bw.Write(imageBytes);
            }
            finally
            {
                fs.Close();
                bw.Close();
            }
        }
}

The top imageUrl declartion is taking in a Base64 image string, and I want to convert it into an image. I think my set of code only works for images like "www.mysite.com/test.jpg" not for a Base64 string. Anybody have some suggestions? Thanks!

Waterloo answered 23/3, 2011 at 2:25 Comment(1)
Try to use: byte[] bytesContent = Convert.FromBase64String(Str64File);Benoite
S
281

Here is an example, you can modify the method to accept a string parameter. Then just save the image object with image.Save(...).

public Image LoadImage()
{
    //data:image/gif;base64,
    //this image is a single pixel (black)
    byte[] bytes = Convert.FromBase64String("R0lGODlhAQABAIAAAAAAAAAAACH5BAAAAAAALAAAAAABAAEAAAICTAEAOw==");

    Image image;
    using (MemoryStream ms = new MemoryStream(bytes))
    {
        image = Image.FromStream(ms);
    }

    return image;
}

It is possible to get an exception A generic error occurred in GDI+. when the bytes represent a bitmap. If this is happening save the image before disposing the memory stream (while still inside the using statement).

Snowden answered 23/3, 2011 at 2:33 Comment(12)
This method gives me black rectangle , do you have any idea ?Midwinter
Yes this is a black pixel: R0lGODlhAQABAIAAAAAAAAAAACH5BAAAAAAALAAAAAABAAEAAAICTAEAOw==Snowden
@Midwinter I would think the black pixel was provided as an example. Try replace the example base64 string with your own base64 stringOmmatophore
@klingdigital Hello , here we had a misunderstanding . and also I found that when sending base64 data from javascript I had some errors that is why my desired image was black .Midwinter
You may need to add a reference to the System.Drawing DLLIm
I get the same error A generic error occurred in GDI+ what we doMatlock
@Matlock did you try saving the image inside the using statement?Snowden
@Snowden Thanks I am use other one save the image is successfullyMatlock
Yes if you don't need to 'convert it to an Image' instance first it can go straight to disk (as the other answers demonstrate).Snowden
Could you, please, specify the full name of the Image class?Charitacharitable
@SasukeUchiha System.Drawing.Image. If you don't need to convert to an Image first you can go straight to disk and not take this dependency.Snowden
This violates a specification in MSDN for Image.FromStream(), where it says "You must keep the stream open for the lifetime of the Image."Baptlsta
S
125

You can save Base64 directly into file:

string filePath = "MyImage.jpg";
File.WriteAllBytes(filePath, Convert.FromBase64String(base64imageString));
Stokehole answered 2/2, 2016 at 17:30 Comment(2)
This is an excellent solution in my case where I was using mono on Linux and experienced some odd behavior with gdi+ in Image.Save. This solution completely bypasses Image / Gdi+ (See #35784190)Anticlinal
I tried both this and @CRice's solution (using Image.Save()). Both work, but for some reason this version makes my file size 30% smaller with no discernible change in image qualityHutto
H
36

Here is what I ended up going with.

    private void SaveByteArrayAsImage(string fullOutputPath, string base64String)
    {
        byte[] bytes = Convert.FromBase64String(base64String);

        Image image;
        using (MemoryStream ms = new MemoryStream(bytes))
        {
            image = Image.FromStream(ms);
        }

        image.Save(fullOutputPath, System.Drawing.Imaging.ImageFormat.Png);
    }
Hiccup answered 26/4, 2013 at 21:3 Comment(2)
This gave me an error A generic error occurred in GDI+ described here. Moving the image.Save inside the using block fixed it for me.Dorcasdorcea
@Dorcasdorcea - Of course it did... The memory stream was already disposed of...Sulphanilamide
F
14

I would suggest via Bitmap:

public void SaveImage(string base64)
{
    using (MemoryStream ms = new MemoryStream(Convert.FromBase64String(base64)))
    {
        using (Bitmap bm2 = new Bitmap(ms))
        {
            bm2.Save("SavingPath" + "ImageName.jpg");
        }
    }
}
Finale answered 7/1, 2013 at 11:33 Comment(1)
what's the difference between converting via bitmap or without bitmap ? thxMendel
B
9

In my case it works only with two line of code. Test the below C# code:

String dirPath = "C:\myfolder\";
String imgName = "my_mage_name.bmp";

byte[] imgByteArray = Convert.FromBase64String("your_base64_string");
File.WriteAllBytes(dirPath + imgName, imgByteArray);

That's it. Kindly up vote if you really find this solution works for you. Thanks in advance.

Barrick answered 1/8, 2016 at 9:44 Comment(3)
It's copy of my answer (see below https://mcmap.net/q/142406/-converting-a-base-64-string-to-an-image-and-saving-it) :)Stokehole
-1 because dirPath has to have an @ sign before the string i..e. @"C:\myfolder\" or you have to escape the backslashes in the string i.e. "C:\\myfolder\\"Salsify
you should provide reference to that other answer instead of taking whole credit....Koblick
E
9

Here is working code for converting an image from a base64 string to an Image object and storing it in a folder with unique file name:

public void SaveImage()
{
    string strm = "R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"; 

    //this is a simple white background image
    var myfilename= string.Format(@"{0}", Guid.NewGuid());

    //Generate unique filename
    string filepath= "~/UserImages/" + myfilename+ ".jpeg";
    var bytess = Convert.FromBase64String(strm);
    using (var imageFile = new FileStream(filepath, FileMode.Create))
    {
        imageFile.Write(bytess, 0, bytess.Length);
        imageFile.Flush();
    }
}
Ensanguine answered 2/5, 2017 at 13:9 Comment(0)
D
7

In a similar scenario what worked for me was the following:

byte[] bytes = Convert.FromBase64String(Base64String);    
ImageTagId.ImageUrl = "data:image/jpeg;base64," + Convert.ToBase64String(bytes);

ImageTagId is the ID of the ASP image tag.

Disunion answered 18/8, 2015 at 19:21 Comment(0)
B
6

If you have a string of binary data which is Base64 encoded, you should be able to do the following:

byte[] encodedDataAsBytes = System.Convert.FromBase64String(encodedData);

You should be able to write the resulting array to a file.

Barnaby answered 23/3, 2011 at 2:36 Comment(2)
This doesn't work. It just converts the base64 string to its binary equivalent. Writing that to a file with an image extension doesn't make it an image.Targe
No? I'm sorry, this is incorrect. Converting a Base64 string to its binary equivalent does not make it an image. (Thanks @Targe for pointing that out!) And, why are you mentioning binary data? This question in no way mentions binary, or even how to convert it.Pasquinade
C
2
public bool SaveBase64(string Dir, string FileName, string FileType, string Base64ImageString)
{
    try
    {
        string folder = System.Web.HttpContext.Current.Server.MapPath("~/") + Dir;
        if (!Directory.Exists(folder))
        {
            Directory.CreateDirectory(folder);
        }

        string filePath = folder + "/" + FileName + "." + FileType;
        File.WriteAllBytes(filePath, Convert.FromBase64String(Base64ImageString));
        return true;
    }
    catch
    {
        return false;
    }

}
Canine answered 27/6, 2020 at 8:33 Comment(1)
While this code may resolve the OP's issue, it is best to include an explanation as to how your code addresses the OP's issue. In this way, future visitors can learn from your post, and apply it to their own code. SO is not a coding service, but a resource for knowledge. Also, high quality, complete answers are more likely to be upvoted. These features, along with the requirement that all posts are self-contained, are some of the strengths of SO as a platform, that differentiates it from forums. You can edit to add additional info &/or to supplement your explanations with source documentation.Periphrasis
B
2

Using MemoryStream is not a good idea and violates a specification in MSDN for Image.FromStream(), where it says

You must keep the stream open for the lifetime of the Image.

A better solution is using ImageConverter, e.g:

public Image ConvertBase64ToImage(string base64)
    => (Bitmap)new ImageConverter().ConvertFrom(Convert.FromBase64String(base64));

Baptlsta answered 28/7, 2021 at 8:5 Comment(1)
That's correct. good solution exactly when you want to use image without saving in local storageCoopersmith
B
0

In NetCore 6.0, you can use HttpClient and the async methods in the new File class.

The implementation is very simple:

static async Task DownloadFile(string imageUrl, string pathToSave)
{
    var content = await GetUrlContent(url);
    if (content != null)
    {       
        await File.WriteAllBytesAsync(pathToSave, content);
    }
}

static async Task<byte[]?> GetUrlContent(string url)
{
    using (var client = new HttpClient())
    using (var result = await client.GetAsync(url))
        return result.IsSuccessStatusCode ? await result.Content.ReadAsByteArrayAsync():null;
}

Usage:

await DownloadFile("https://example.com/image.jpg", @"c:\temp\image.jpg");
Bypath answered 5/4, 2022 at 10:39 Comment(0)
W
0

you can convert a base64 string to an image and save it using the following code. This example assumes you're working with a console application, but the core logic can be adapted for other types of projects.

using System;
using System.Drawing;
using System.IO;

class Program
{
     static void Main()
       {
    // Replace this string with your actual base64-encoded image
    string base64String = "your_base64_encoded_string_here";

    // Convert base64 to bytes
    byte[] imageBytes = Convert.FromBase64String(base64String);

    // Convert bytes to image
    Image image = ConvertBytesToImage(imageBytes);

    // Specify the path to save the image
    string filePath = "path_to_save_image.png";

    // Save the image to the specified path
    SaveImage(image, filePath);

    Console.WriteLine($"Image saved at: {filePath}");
}

static Image ConvertBytesToImage(byte[] imageBytes)
{
    using (MemoryStream ms = new MemoryStream(imageBytes))
    {
        Image image = Image.FromStream(ms);
        return image;
    }
}

static void SaveImage(Image image, string filePath)
{
    image.Save(filePath, System.Drawing.Imaging.ImageFormat.Png);
}

}

Weatherman answered 6/12, 2023 at 12:33 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.