Retrieving only half the Image when converting to Base64 - c#

I have an API which reads an uploaded Image and changes it to a byte[], however in the database the field for where I have to save the image is a string instead of varbinary(MAX), and I cannot change the field type of the database.
I thought about converting the image to base64 and then storing it but this might cause unnecessary strain on the database.
I have found online the following way but this method can be inconsistent based on the server as the encoding might change:
var str = System.Text.Encoding.Default.GetString(result);
And if I were to use the above method I would need to know what type of encoding does ReadBytes use.
Below is my code:
byte[] fileData = null;
using (var binaryReader = new BinaryReader(image.InputStream))
{
binaryReader.BaseStream.Position = 0;
fileData = binaryReader.ReadBytes(image.ContentLength);
}
Furthermore, when I converted the image to a base64 and viewed it, only half the image was visible:
var base64String = Convert.ToBase64String(fileData);

use Convert.toBase64String() method or just using MemoryStream class->
// 1.toBase64String()
string str = Convert.ToBase64String(bytes);
// 2.MemoryStream class
using (MemoryStream stream = new MemoryStream(bytes))
using (StreamReader streamReader = new StreamReader(stream))
{
return streamReader.ReadToEnd();
}

Initialize the BinaryReader with this overload that specifies the encoding.
var binaryReader = new BinaryReader(System.IO.Stream input, System.Text.Encoding encoding);

Related

Image not Reconstructing by the Byte[] array retrived using asp.net WebAPI in JSON format

This is how ImageBytes Generated
Stream stream = postedFile.InputStream;
BinaryReader binaryReader = new BinaryReader(stream);
imgBytes = binaryReader.ReadBytes((int)stream.Length);
Explanation: These imgBytes then POSTED to DB using webAPI 2 and when these bytes retrieved from DB using GET method in JSON format and then converted to Base64String but image is not generated
Retrived Using GET Method in JSON format
var jsonString = response.Content.ReadAsStringAsync().Result;
byte[] mapbytes = System.Text.Encoding.UTF8.GetBytes(jsonString);
String base64String = Convert.ToBase64String(mapbytes);
String src = "data:image/png;base64," + base64String;
Note
already tried all the posted answer on stackoverflow but didn't get solution
also convert from JSON to Byte[] using
byte[] mapbytes =Encoding.ASCII.GetBytes(response.Content.ReadAsStringAsync().Result);

Converting a byte[] string back to byte[] array

I have one scenario with class like this.
Class Document
{
public string Name {get;set;}
public byte[] Contents {get;set;}
}
Now I am trying to implement the import export functionality where I keep the document in binary so the document will be in json file with other fields and the document will be something in this format.
UEsDBBQABgAIAAAAIQCitGbRsgEAALEHAAATAAgCW0NvbnRlbnRfVHlwZXNdLnhtbCCiBAIooAACAAAAAAA==
Now when I upload this file back, I get this file as a string and I get the same data but when I try to convert this in binary bytes[] the file become corrupt.
How can I achieve this ?
I use something like this to convert
var ss = sr.ReadToEnd();
MemoryStream stream = new MemoryStream();
StreamWriter writer = new StreamWriter(stream);
writer.Write(ss);
writer.Flush();
stream.Position = 0;
var bytes = default(byte[]);
bytes = stream.ToArray();
This looks like base 64. Use:
System.Convert.ToBase64String(b)
https://msdn.microsoft.com/en-us/library/dhx0d524%28v=vs.110%29.aspx
And
System.Convert.FromBase64String(s)
https://msdn.microsoft.com/en-us/library/system.convert.frombase64string%28v=vs.110%29.aspx
You need to de-code it from base64, like this:
Assuming you've read the file into ss as a string.
var bytes = Convert.FromBase64String(ss);
There are several things going on here. You need to know the encoding for the default StreamWriter, if it is not specified it defaults to UTF-8 encoding. However, .NET strings are always either UNICODE or UTF-16.
MemoryStream from string - confusion about Encoding to use
I would suggest using System.Convert.ToBase64String(someByteArray) and its counterpart System.Convert.FromBase64String(someString) to handle this for you.

Decode large Base64 strings

I have an input string from a WebService in the form of a roughly 70 MB large base64-encoded string.
I want to decode this into a file, and tried the obvious: using Convert.FromBase64String().
This, however, yields a OutOfMemoryException. After some reading, I discovered that the Convert methods concerned with Base64
leak memory (no doubt due to the immutable nature of strings and some poor design inside the framework methods)
source
and there is a handy "streamed" replacement in the System.Security.Cryptography namespace: FromBase64Transform.
So, I decided to give that a try, but I need to input the method an array of bytes, which I don't have - I have a string.
How can I convert the string I have into bytes without running into another OutOfMemoryException on that transformation again?
Although you probably could turn your string into a byte array in memory without worrying about memory usage, here's how you can stream the transformation:
var input = "abcdefghijklmnop";
byte[] output;
using (var ms = new MemoryStream())
using (var cs = new CryptoStream(ms, new FromBase64Transform(), CryptoStreamMode.Write))
using (var tr = new StreamWriter(cs))
{
tr.Write(input);
tr.Flush();
output = ms.ToArray();
}
If you replace the MemoryStream with a suitable FileStream you can stream directly to file rather than an array:
var input = new string('a', 400000000);
byte[] output;
using (var ms = new FileStream(Guid.NewGuid().ToString() + ".bin", FileMode.Create))
using (var cs = new CryptoStream(ms, new FromBase64Transform(), CryptoStreamMode.Write))
using (var tr = new StreamWriter(cs))
{
tr.Write(input);
tr.Flush();
}
You should use Encoding.ASCII.GetBytes() or similar to convert your string back to the original ASCII which was used to transmit the base64-encoded data.
I am curious about how you received the string from the WebService in the first place. Is it possible that you can skip the conversion to a .NET string and just pass the bytes received directly to the transform? That would be more efficient.

Generic GDI+ error (error number -2147467259)

My friends,
I am trying convert a image to a Base64 String in a c# console app (.net 4.0).
The method:
public static String ConvertBitmapToBase64String(Bitmap bitmap,
ImageFormat imageFormat)
{
String generatedString = string.Empty;
MemoryStream memoryStream = new MemoryStream();
bitmap.Save(memoryStream, imageFormat);
memoryStream.Position = 0;
byte[] byteBuffer = memoryStream.ToArray();
memoryStream.Close();
generatedString = Convert.ToBase64String(byteBuffer);
byteBuffer = null;
return generatedString;
}
But when I invoke this method it is throwing an exception saying: "generic gdi+ error" and the error number is -2147467259.
Invoker code:
StreamReader streamReader = new StreamReader(#"C:\Anita.jpg");
Bitmap bitmap = new Bitmap(streamReader.BaseStream);
streamReader.Close();
String base64String = ImageUtil.ConvertBitmapToBase64String(bitmap, ImageFormat.Jpeg);
Anybody can give me a help?
Thanks.
The only likely problem I see is that the image is too large or big. Perhaps, instead of using a MemoryStream, you can use File.ReadAllBytes directly instead of passing around the Bitmap object, saving directly to a MemoryStream, and saving.
Also, you're reading the data in with a StreamReader, which is meant for text! Moving to just reading the bytes into an array and calling Convert.ToBase64String() should handle what you want to do.

Can encode/decode a Image Object to keep it in a XML file using Compact Framework?

As the title mentioned, I want to encode a Image Obj into some kind of text data (compact framework not support binaryformatter, correct me if I'm wrong). So is there any way to encode a Image Obj into text data and keep it in a XML file for being able to decode from XML file to Image obj later?
UPDATE: Here is what I did following Sam's respose. Thanks Sam!
//Write to XML
byte[] Ret;
using (MemoryStream ms = new MemoryStream())
{
myImage.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
Ret = ms.ToArray();
}
StreamWriter myWrite = new StreamWriter(myPathFile);
myWrite.Write(Convert.ToBase64String(Ret));
myWrite.Flush();
myWrite.Close();
Then when I want to decode Image from Base64String to Image:
StreamReader StrR = new StreamReader(myPathFile);
BArr = Convert.FromBase64String(StrR.ReadToEnd());
using (MemoryStream ms = new MemoryStream(BArr,0,BArr.Length))
{
ms.Write(BArr, 0, BArr.Length);
listControl1.BGImage = new Bitmap(ms);
}
Typically binary data is converted to Base64 when included in XML. Look at Convert.ToBase64String.

Categories