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.
Related
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);
I'm doing a C# web service soap receiving an image.
I send a string contain the byte characters.
I transform the string in byte[] and next I world like to create the Bitmap.
The line Bitmap img = new Bitmap(ms); generate an exception : invalid argument.
I have a in the ms object this error : System.InvalidOperationException
value contain the correct string, imgBytes contain the good number of sell.
public string GetImage(string value)
{
byte[] imgBytes = Encoding.ASCII.GetBytes(value);
MemoryStream ms = new MemoryStream(imgBytes, true);
Bitmap img = new Bitmap(ms);
Code with debug mode
Exception
Thank you for your help.
It looks like your string holds base64 encoded data. Try to decode it to a byte array via Convert.FromBase64String
I had a similar problem. Basically you write into your memory stream (in the constructor) and the position pointer is at the end. So before reuse the memory stream you can try setting its position pointer to the beginning. Like this:
MemoryStream ms = new MemoryStream(imgBytes, true);
ms.Position = 0;
Bitmap img = new Bitmap(ms);
or the more general approach:
MemoryStream ms = new MemoryStream(imgBytes, true);
ms.Seek(0, SeekOrigin.Begin);
Bitmap img = new Bitmap(ms);
Hope this will solve your Problem.
Update
I think #heinbeinz answer is also important: First decode your string from the right encoding (normally base64), then set the position.
I would need to take a screenshot, if easy to without saving it. I would sent the image data directly to a PHP script. Because I don't have this PHP script at the moment, so I search for the easiest way of format in which I should convert the screenshot data. For debugging reasons until I've got my PHP script I would like to convert a picture of these data on my client side using C#.
My code at the moment for taking a screenshot and convert it (I'm not sure if I can convert the output in my logfile back into a picture):
internal static byte[] ImageToByteArray(Image img)
{
byte[] byteArray = new byte[0];
MemoryStream stream = new MemoryStream();
img.Save(stream, System.Drawing.Imaging.ImageFormat.Png);
stream.Close();
byteArray = stream.ToArray();
return byteArray;
}
public static string TakeScreenshot()
{
String filepath = #"C:\log2.txt";
Bitmap bitmap = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height, PixelFormat.Format32bppArgb);
Graphics graphics = Graphics.FromImage(bitmap);
graphics.CopyFromScreen(Screen.PrimaryScreen.Bounds.X, Screen.PrimaryScreen.Bounds.Y, 0, 0, Screen.PrimaryScreen.Bounds.Size, CopyPixelOperation.SourceCopy);
graphics.Dispose();
bitmap.Save("C:\\temp.png");
Image img = (Image)bitmap;
string str = System.Text.Encoding.Default.GetString(ImageToByteArray(img));
System.IO.File.AppendAllText(filepath, str);
//just for debugging
return "OH";
}
Main question at the moment, is there any way to get a picture back from my converted code (log2.txt).
This line of code:
string str = System.Text.Encoding.Default.GetString(ImageToByteArray(img));
Will almost certainly not do what you want it to do. It will try to interpret your byte array as a string in whatever is the default character encoding on your machine. If the default is something like UTF-8 or any multibyte character set, then it's quite likely to fail. Even if the default encoding is a single-byte character set, it could create a string that can't be reliably turned back into the original byte array.
If you really want to store the byte array as text, you can call Convert.ToBase64String:
string str = Convert.ToBase64String(ImageToByteArray(img));
If you read that string back from the file into str, you can rebuild the byte array with:
byte[] imageBytes = Convert.FromBase64String(str);
Another advantage in your particular case is that there are PHP functions for dealing with base 64 strings.
How do I convert an object of BitmapImage type to a byte array?
There's plenty of examples out on the web but all of them are using methods that no longer exist for windows Store app.
best solution I've found is this, however I get an exception on the first code line when trying to run it
public static byte[] ConvertBitmapToByteArrayAsync(WriteableBitmap bitmap)
{
using (var stream = bitmap.PixelBuffer.AsStream())
{
MemoryStream memoryStream = new MemoryStream();
stream.CopyTo(memoryStream);
return memoryStream.ToArray();
}
}
exception:
A first chance exception of type 'System.AccessViolationException'
occurred in System.Runtime.WindowsRuntime.dll
Additional information: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
from what I can gather it may have to do with the size of the stream but I haven't been able to figure out how to fix it.
I hope this can help you:
// Converting Bitmap to byte array
private byte[] ConvertBitmapToByteArray(Bitmap imageToConvert)
{
MemoryStream ms = new System.IO.MemoryStream();
imageToConvert.Save(ms, ImageFormat.Png);
return ms.ToArray();
}
// Converting byte array to bitmap
private Bitmap ConvertBytesToBitmap(byte[] BytesToConvert)
{
MemoryStream ms = new MemoryStream(BytesToConvert);
try { return new Bitmap(ms); }
catch { return null; }
}
I want to convert an image to base64 and back to image again.
Here is the code which i tried so far and the error also. Any suggestions please?
public void Base64ToImage(string coded)
{
System.Drawing.Image finalImage;
MemoryStream ms = new MemoryStream();
byte[] imageBytes = Convert.FromBase64String(coded);
ms.Read(imageBytes, 0, imageBytes.Length);
ms.Seek(0, SeekOrigin.Begin);
finalImage = System.Drawing.Image.FromStream(ms);
Response.ContentType = "image/jpeg";
Response.AppendHeader("Content-Disposition", "attachment; filename=LeftCorner.jpg");
finalImage.Save(Response.OutputStream, ImageFormat.Jpeg);
}
The error is :
Parameter is not valid.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.ArgumentException: Parameter is not valid.
Source Error:
Line 34: ms.Read(imageBytes, 0, imageBytes.Length);
Line 35: ms.Seek(0, SeekOrigin.Begin);
Line 36: finalImage = System.Drawing.Image.FromStream(ms);
Line 37:
Line 38: Response.ContentType = "image/jpeg";
Source File: e:\Practice Projects\FaceDetection\Default.aspx.cs Line: 36
You are reading from an empty stream, rather than loading the existing data (imageBytes) into the stream. Try:
byte[] imageBytes = Convert.FromBase64String(coded);
using(var ms = new MemoryStream(imageBytes)) {
finalImage = System.Drawing.Image.FromStream(ms);
}
Also, you should endeavour to ensure that finalImage is disposed; I would propose:
System.Drawing.Image finalImage = null;
try {
// the existing code that may (or may not) successfully create an image
// and assign to finalImage
} finally {
if(finalImage != null) finalImage.Dispose();
}
And finally, note that System.Drawing is not supported on ASP.NET; YMMV.
Caution
Classes within the System.Drawing namespace are not supported for use within a Windows or ASP.NET service. Attempting to use these classes from within one of these application types may produce unexpected problems, such as diminished service performance and run-time exceptions. For a supported alternative, see Windows Imaging Components.
The MemoryStream.Read Method reads bytes from the MemoryStream into the specified byte array.
If you want to write the byte array to the MemoryStream, use the MemoryStream.Write Method:
ms.Write(imageBytes, 0, imageBytes.Length);
ms.Seek(0, SeekOrigin.Begin);
Alternatively, you can simply wrap the byte array in a MemoryStream:
MemoryStream ms = new MemoryStream(imageBytes);