Save Base 64 encoded images to a file in C#

The ability to copy/paste images into editors is extremely handy for end users.  It's a feature available in CKEditor, but one problem with the default implementation is that images are inserted as Base 64 encoded strings. This means instead of having a physical file that the image references, the source of the image is all stored as a long string with your content. This can be great for small images, but not so great with larger files.

For CKEditor there are several plugins that help tackle this by automatically saving your images to a file as you copy/paste them.  The downside there is frequently a user will add an image, and then remove it from the editor, or decide not to add their content. In those cases the file will still reside on the server taking up space since it was created as soon as the user copied/pasted it.

After looking around we couldn't find any solution that met our needs so we created our own. The code basically takes a string of text and looks for any base 64 encoded images (by using a regular expression). If there are any matches the system loops through each match and extracts the content of the image as well as the mime type. It then saves the image to a physical location and returns a string with all the image tags no longer using the base 64 encoded image, but instead referencing the new physical location.

In our system we call this code anytime a user saves their content, that way we are only saving images to the server as necesary. The code below contains comments to help you make sense of it. For the code to work in your environment the only variable you need to change is the one that sets directory where you want to save the images (dirPath).  



This code is provided as is and we make no warranty and are not responsible for any issues caused by executing it in your environment  

public static string saveImagesFromBase64(String strContent)
        //find all images
        string pattern = @"(<img.*?src=\""data:.*?\/>)";
        MatchCollection match1 = Regex.Matches(strContent, pattern, RegexOptions.Singleline | RegexOptions.Compiled);
        // Loop over each match.
        foreach (Match m in match1)
            string value = m.Groups[1].Value;
            var regex = new Regex(@"data:(?<mime>[\w/\-\.]+);(?<encoding>\w+),(?<data>.*)\"" \/>", RegexOptions.Singleline | RegexOptions.Compiled);
            var match = regex.Match(value);
            var mime = match.Groups["mime"].Value;
            var encoding = match.Groups["encoding"].Value;
            var data = match.Groups["data"].Value;
            String dirPath = HttpRuntime.AppDomainAppPath + "uploads\\images\\auto\\";

            if (!Directory.Exists(dirPath))
            String FileName = Guid.NewGuid().ToString().Replace("-", string.Empty).Substring(0, 8) + "-" + string.Format("{0:yyyy-MM-dd_hh-mm-ss-tt}", DateTime.Now);
            string filetype = "";
            if (mime == "image/png")
                filetype = ".png";
            else if (mime == "image/jpg")
                filetype = ".jpg";
            else if (mime == "image/gif")
                filetype = ".gif";
            byte[] imgByteArray = Convert.FromBase64String(data);
            File.WriteAllBytes(dirPath + FileName + filetype, imgByteArray);
            strContent = strContent.Replace(value, "<img src=\"uploads/images/auto/" + FileName + filetype + "\" />");
        return strContent;


Tags: Development , , C# ,

Just Some of our Happy Clients...