I am getting an exception when trying to convert a base64 string to a byte array. I am converting an Image to a byte array then to a base64 string, then encrypting it and storing it in a file. Then I am attempting to convert the base64 string back to a byte array in a MemoryStream, and recreating the image. I am getting a FormatException here:
byte[] imgBytes = Convert.FromBase64String(str);
Here is the full code for the two main functions:
public string ImageToString(Image img)
{
using (MemoryStream ms = new MemoryStream())
{
img.Save(ms, ImageFormat.Jpeg);
return Convert.ToBase64String(ms.ToArray());
}
}
public Image StringToImage(String str)
{
int lent = str.Length;
byte[] imgBytes = Convert.FromBase64String(str);
MemoryStream ms = new MemoryStream(imgBytes, 0, imgBytes.Length);
ms.Write(imgBytes, 0, imgBytes.Length);
return Image.FromStream(ms, true);
}
Here is the beginning and end of the base64 string I am trying to convert....
G>/9j/4AAQSkZJRgABAQEAYABgAAD .... Uh+8fxpT/B9KAP/2Q==
Any ideas are greatly appreciated!
The problem is that your string got corrupted somewhere along the line. That's not a base64 string, as you can see by the second charcter >, which does not occur in a base64 string.
Side note: Your function creates a memory stream containing the data, then writes the data to the memory stream again. Then you try to read from the memory stream without resetting the position to the beginning of the stream.
Just create the memory stream and read from it:
public Image StringToImage(String str) {
byte[] imgBytes = Convert.FromBase64String(str);
return Image.FromStream(new MemoryStream(imgBytes), true);
}
Related
I get the following error: The archive entry was compressed using an unsupported compression method.
I got to decode the following gzip compressed base64 string, here is the string:
H4sIAAAAAAAAAD1SwW6bQBAdO0mDrUq9VGoPPWzVSj1ZItiO7aNjk4TI4IRgY7gtMLZxFnBhiYM/oLee+wn8QL+AT+mHVF1y6F5WM+/N07yZaQO0oBG2AaDRhGYYNH424GyS5DFvtOGE000LTjH2t1C/E2jdhgFeM7rJRPi3De3Hp5yx+SHGVIKmFsBX2R8gri96nXXf9zpduT/seArKHcWnA2WoKD30B6LuPk32mPIQsxZIHF94nmL22oYEZ0vKcoTfWNzJ7morB6s75hfapYitR5nNtd1+oMXLwptol1ok8Nur4zwcPgc3y15wuyzclZ57Nstd2ygc25VnUZ8Fk9F/rdnRL3RLlR1rc9CPi64xdY5utCjc3aLvWnrfUK63zo5FztFR3OlDT49UxbAfLvSdGc2nm65+81Dott4V8U63tsxRnK5h+eF6dTESDtpwHoTZntFCzG6WpCi9Jt9X5dDE73kojBKGz8iIIoMksldJwut5fqjKgU3ZUxh/I0lMUhrGXnLIPgvoi4DG+z0rCN+GGUnzGAlPiFdXkiQl6zxD+CRI/JAIYIN8iymhXNCRmHkc+vBWoPcYYMYpqyU/VuVlVbKZeqMa07HpkMn8UVctbSLBqUEjhE5VBn9+/SBV6ZuCS6sSw6qkcVV6XlWOEgEfxF/LI9GEw3fqC0/pmPM09HJer/OsbjQ7gXNzrBlXc7veL0j1ncGpuTBUgCa8mdKIblAcF/wDb9VytI4CAAA\u003d
When I first use the Convert.FromBase64String method I receive this string when I convert it into a string:
a"\u001f�\b\0\0\0\0\0\0\0=R�n�#\u0010\u001d;I��J�Tj\u000f=l�J=Y"؎��c�����c�-0�q\u0016pa��?����\t�#��O�T]r�^V3��Ӽ�i\u0003��\u0011�\u0001�фf\u00184~6�l��1o���M\vN1��P�\u0013h݆\u0001^3��D��\r�ǧ���!�T��\u0016�W�\u001f �/z�u��:]�?�x\n�\u001dŧ\u0003e�(=�\a��>M���\u0010�\u0016H\u001c_x�b�چ\u0004gK�r��X���j+\a�;�\u0017ڥ��G�͵�~���\u009bh�Z$�۫�<\u001c>\a7�^p�,ܕ�{6�]�(\u001cەgQ�\u0005��\u007f���/tK�\u001dksЏ��1u�n�(�ݢ�Zz�P��ΎE��Q��CO�TŰ\u001f.��\u0019ͧ��~�P��\u0015�N���Q��a��zu1\u0012\u000e�p\u001e�ٞ�B�n��(�&�W����y(�\u0012��Ȉ\"�$�WI��y~�ʁM�S\u0018\u007f#ILR\u001a�^r�>\v苀��=+\b߆\u0019I�\u0018\tO�WW�$%�<C�$H��\b�|�)�\Б�y\u001c��V��\u0018`�)�%?V�eU��z�\u001aӱ���QW-m"��A#�NU\u0006\u007f~� U雂K�\u0012ê�qUz^U�\u0012\u0001\u001f�_�#ф�w�\vO��4�r^��n4;�ss�\u0019Ws��/H�����0T�&��҈nP\u001c\u0017�\u0003o�r��\u0002\0\0"
could this have something to do with the problem?
Here is my code:
public static string Decompress(string input)
{
byte[] compressed = Convert.FromBase64String(input);
byte[] decompressed = Decompress(compressed);
return Encoding.UTF8.GetString(decompressed);
}
private static byte[] Decompress(byte[] input)
{
using (var source = new MemoryStream(input))
{
byte[] lengthBytes = new byte[4];
source.Read(lengthBytes, 0, 4);
var length = BitConverter.ToInt32(lengthBytes, 0);
using (var decompressionStream = new GZipStream(source,
CompressionMode.Decompress))
{
var result = new byte[length];
decompressionStream.Read(result, 0, length); Error: The archive entry was compressed using an unsupported compression method.
return result;
}
}
}
There is one little oddity in the base64 string, though it should not result in the error message you are getting. the \u003d should be replaced an equal sign (=), in order for the base64 decoding to work properly. (I can't tell if the string actually has those five characters at the end, or if it is just a representation of a string with an equal sign at the end. In the latter case, I don't know it wouldn't just show an equal sign as opposed to a unicode escaped representation of an equal sign.)
Otherwise, that base64 string decodes to a valid gzip stream that should decompress with no problem.
I solved the issue, I use the GZipStream.CopyTo to a MemoryStream in place of the read function. Here is the code if anyone would need it!
public static string Decompress(string value)
{
byte[] buffer = Convert.FromBase64String(value);
byte[] decompressed;
using (var inputStream = new MemoryStream(buffer))
{
using var outputStream = new MemoryStream();
using (var gzip = new GZipStream(inputStream, CompressionMode.Decompress, leaveOpen: true))
{
gzip.CopyTo(outputStream);
}
decompressed = outputStream.ToArray();
}
return Encoding.UTF8.GetString(decompressed);
}
While grabbing images (Image type) to convert them into "Base64 String" in a kind of loop, im always getting this error at a random time of the execution.
"Unhandled Exception: System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt."
private void doCapture()
{
CaptureInfo.CaptureFrame();
}
void CaptureInfo_FrameCaptureComplete(PictureBox Frame)
{
string str = toB64img(Frame.Image);
//do something with the string
this.doCapture();
}
private string toB64img(Image image)
{
using (MemoryStream ms = new MemoryStream())
{
// Convert Image to byte[]
image.Save(ms, ImageFormat.Png); <==== error HERE
byte[] imageBytes = ms.ToArray();
// Convert byte[] to Base64 String
string base64String = Convert.ToBase64String(imageBytes);
return base64String;
}
}
Image come from directx.capture, webcam capture. (working fine)
I assume that's because something is still in access and wasn't closed yet, so error cause already in use. But how can i fix this issue please?
i was right in my though.
Something wasn't freed fast enought.
Adding a force GC check right before the RETURN of the function, worked like a charm.. strange.
private string toB64img(Image image)
{
using (MemoryStream ms = new MemoryStream())
{
// Convert Image to byte[]
image.Save(ms, ImageFormat.Png);
byte[] imageBytes = ms.ToArray();
// Convert byte[] to Base64 String
string base64String = Convert.ToBase64String(imageBytes);
GC.Collect(); <======
GC.WaitForPendingFinalizers(); <======
GC.Collect(); <======
return base64String;
}
}
``
Converting a multi page tiff file to base64 string by using known conversion methods seems to contain just a single page of it.
I'm getting the multi page tiff file from local disk:
Image multiPageImage = Image.FromFile(fileName);
Converting it to base64 string:
base64string = ImageToBase64(multiPageImage, ImageFormat.Tiff);
public static string ImageToBase64(Image image, ImageFormat format)
{
using (MemoryStream ms = new MemoryStream())
{
// Convert Image to byte[]
image.Save(ms, format);
byte[] imageBytes = ms.ToArray();
// Convert byte[] to Base64 String
string base64String = Convert.ToBase64String(imageBytes);
image.Dispose();
return base64String;
}
}
Then converting base64 to image back and saving it on the local disk to control the result:
public static Image ConvertBase64ToImage(string base64string)
{
byte[] bytes = Convert.FromBase64String(base64string);
Image image;
using (MemoryStream ms = new MemoryStream(bytes))
{
image = Image.FromStream(ms);
image.Save(#"C:\newTiff.tiff", ImageFormat.Tiff);
}
return image;
}
But result image has only single frame. That's why I'm asking if it is possible to have all frames in base64 string?
You are doing lot of unnecessary stuff just for reading a file and write it back to disk.
You can read all the content of file like this
var data = File.ReadAllBytes("image.tiff")
and then use Convert.ToBase64String(data) to convert it to a base 64 string.
var data = File.ReadAllBytes("image.tiff");
var result = Convert.ToBase64String(data);
then you can convert it back to it's byte representation and save it to disk.
var bytes = Convert.FromBase64String(result);
File.WriteAllBytes("image2.tiff", bytes);
File.ReadAllBytes()
Convert.ToBase64String()
I'm making multi client chat server(done).
but I want to add image send.
I used this method when sending a message
client1 write message and getbyte -> Server -> getstring
So I'm coding like this (I can't this part)
load image -> ImageToBase64(image) -> getbyte --> server --> getstring-> Base64ToImage
Client Send part
how can i use this function and this method can be run.
private void button1_Click(object sender, EventArgs e)
{
Image screen;
screen=Image.FromFile("C:\\Users\\User\\Desktop\\Paint.bmp");
screentext = ImageToBase64(screen); //actually I do not know what parameter should be here
StreamWriter wrthr = new StreamWriter(#"C:\Users\User\Desktop\giden.txt");
wrthr.Write(screentext);
wrthr.Close(); // result empty txt
}
public string ImageToBase64(Image image, System.Drawing.Imaging.ImageFormat format)
{
using (MemoryStream ms = new MemoryStream())
{
// Convert Image to byte[]
image.Save(ms, format);
byte[] imageBytes = ms.ToArray();
// Convert byte[] to Base64 String
string base64String = Convert.ToBase64String(imageBytes);
return base64String;
}
}
public Image Base64ToImage(string base64String)
{
// Convert Base64 String to byte[]
byte[] imageBytes = Convert.FromBase64String(base64String);
MemoryStream ms = new MemoryStream(imageBytes, 0,
imageBytes.Length);
// Convert byte[] to Image
ms.Write(imageBytes, 0, imageBytes.Length);
Image image = Image.FromStream(ms, true);
return image;
}
EDIT: There are two problems here...
Picking a second argument to ImageToBase64
It's up to you - do you want to keep it as a BMP file? If so, you don't really need to go via an Image at all... just load the bytes from Paint.bmp, and convert them directly into Base64:
byte[] bytes = File.ReadAllBytes(#"C:\Users\User\Desktop\Paint.bmp");
File.WriteAllText(#"C:\Users\User\Desktop\giden.txt",
Convert.ToBase64String(bytes));
Or you may wish to choose a different format, e.g. PNG or JPEG, e.g.
string screentext = ImageToBase64(screen, ImageFormat.Png);
(It's not clear where screentext is declared at the moment, but it should almost certainly be a local variable.)
Converting from base64...
This is the problem:
MemoryStream ms = new MemoryStream(imageBytes, 0,
imageBytes.Length);
// Convert byte[] to Image
ms.Write(imageBytes, 0, imageBytes.Length);
You don't need the Write call, and it's actively harmful here:
You've constructed the MemoryStream with imageBytes, so it already contains that data
By writing to the stream, you've moved the "cursor" to the end... so there's nothing to read
Just use:
public Image Base64ToImage(string base64String)
{
// Convert Base64 String to byte[]
byte[] imageBytes = Convert.FromBase64String(base64String);
MemoryStream ms = new MemoryStream(imageBytes);
return Image.FromStream(ms, true);
}
I'm trying to store images (png) to sqlite database in a windows 8 app, and i figured out it can be done by converting it to base64 string and storing the string to the database. Later on in the app i want to convert that base64 string to png image and store it to a specified location. The Problem is i don't know how to convert images to base64 and base64 to image and store it to a specified location in c# windows 8 app. Any help would be appreciated.
public string ImageToBase64(Image image,
System.Drawing.Imaging.ImageFormat format)
{
using (MemoryStream ms = new MemoryStream())
{
// Convert Image to byte[]
image.Save(ms, format);
byte[] imageBytes = ms.ToArray();
// Convert byte[] to Base64 String
return Convert.ToBase64String(imageBytes);
}
}
public Image Base64ToImage(string base64String)
{
// Convert Base64 String to byte[]
byte[] imageBytes = Convert.FromBase64String(base64String);
using (var ms = new MemoryStream(imageBytes, 0, imageBytes.Length))
{
// Convert byte[] to Image
ms.Write(imageBytes, 0, imageBytes.Length);
return Image.FromStream(ms, true);
}
}