9

I have following base 64 image:

var image='data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAA0gA...';

I am using Convert.FromBase64String()to convert this to bytes:

 byte[] bytes = Convert.FromBase64String(convert);

But before this, I need to strip out the header of Base 64 string (i.e data:image/png;base64). I am doing this using:

string convert = image.Replace("data:image/png;base64,", string.Empty);

I can write the same statement for all image extensions separately, but these images are very large and scanning through each one seems inefficient.

I searched this solution which uses regular expression in PHP to cut off the header part, while other answer in PHP uses an inbuilt method get_contents.

My Question is: Is there any inbuilt method to get only contents of base 64 url in C#? If not, then is there any generalized way to strip out header for all extensions?

Community
  • 1
  • 1
Karan Desai
  • 3,012
  • 5
  • 32
  • 66
  • It's a fixed length string that's always at the start of the string, right? Just `image.Substring("data:image/png;base64,".Length)` should work. – Blorgbeard Sep 01 '16 at 09:07
  • I googled your problem, and I can say, there is no inbuilt function for that. However, what's stopping you from writing your own function? Take in a string and output a formatted string without the `data:image/png;base64,`. – Keyur PATEL Sep 01 '16 at 09:08
  • @Blorgbeard it is not always a fixed length:if extensions are of 4 characters like jpeg,TIFF etc or even more than 4, then I will have to rewrite everything again; that's why I asked for a generalized solution, if any. – Karan Desai Sep 01 '16 at 09:18
  • @KeyurPATEL The extension in header part may be different. I have provided an example of png in question to provide an idea. Therefore I want a way to format the string even if the extensions change. – Karan Desai Sep 01 '16 at 09:20

3 Answers3

17

You could try something like this:

string result = Regex.Replace(image, @"^data:image\/[a-zA-Z]+;base64,", string.Empty);

this should catch the different extensions. I haven't tested this though so it might need some fiddling with.

Leniel Maccaferri
  • 100,159
  • 46
  • 371
  • 480
Ronan
  • 583
  • 5
  • 20
16

Since you know the only instance of , in the string will be the separator between the preamble and the data, you could do it without regex like this:

string convert = image.Substring(image.IndexOf(",") + 1);
Blorgbeard
  • 101,031
  • 48
  • 228
  • 272
  • I wish I could mark two answers as accepted. This solution also works perfectly well. Thanks for the alternative. – Karan Desai Sep 01 '16 at 09:30
3

You can use String.Split method.

String[] substrings = image.Split(',');

string header = substrings[0];
string imgData = substrings[1]; 

byte[] bytes = Convert.FromBase64String(imgData);

UPDATE

Out of curiosity, I wrote a test which method is the fastest.

using System;
using System.Text.RegularExpressions;

namespace StackOwerflow
{
    public class Program
    {
        static public void Main()
        {
            int repeats = 10000;

            string imgStr = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAB0IAAAQ4CAIAA...eXiM/H/wAAAABJRU5ErkJggg=="; //146 kb img file
            string r = string.Empty;

            var watch = System.Diagnostics.Stopwatch.StartNew();
            for (int i = 0; i < repeats; i++)
            {
                r = RegExMethod(imgStr);
            }
            watch.Stop();
            var elapsedMs = watch.ElapsedMilliseconds;

            Console.WriteLine("RegEx time: {0} Ms", elapsedMs);

            watch = System.Diagnostics.Stopwatch.StartNew();
            for (int i = 0; i < repeats; i++)
            {
                r = SubStringMethod(imgStr);
            }
            watch.Stop();
            elapsedMs = watch.ElapsedMilliseconds;

            Console.WriteLine("SubString time: {0} Ms", elapsedMs);

            watch = System.Diagnostics.Stopwatch.StartNew();
            for (int i = 0; i < repeats; i++)
            {
                r = SplitMethod(imgStr);
            }
            watch.Stop();
            elapsedMs = watch.ElapsedMilliseconds;

            Console.WriteLine("Split time: {0} Ms", elapsedMs);

            Console.ReadKey();
        }

        public static string RegExMethod(string img)
        {
            return Regex.Replace(img, @"^data:image\/[a-zA-Z]+;base64,", string.Empty);
        }

        public static string SubStringMethod(string img)
        {
            return img.Substring(img.IndexOf(",") + 1);
        }

        public static string SplitMethod(string img)
        {
            return img.Split(',')[1];
        }

    }
}

And for my machine results:

RegEx time: 1022 Ms

SubString time: 1188 Ms

Split time: 5255 Ms

And the winner is RegEx.

BWA
  • 5,672
  • 7
  • 34
  • 45