Reputation: 3142
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?
Upvotes: 11
Views: 14830
Reputation: 613
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.
Upvotes: 19
Reputation: 5764
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.
Upvotes: 5
Reputation: 103467
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);
Upvotes: 17