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.
Related
I have a C# project that uses Convert.FromBase64String(string) that builds properly in VS2019 but in VS22, the output dll gets immediately quarantined by CrowdStrike. I can't explain why CrowdStrike only finds potential security issues with VS22 and not VS2019.
Is there a way to create an image from Base64 without the use of FromBase64String?
I've found leaving the data:image/png;base64 header in the string allows the project to build and output the dll but Convert.FromBase64String(string) fails with 'The input is not a valid Base-64 string as it contains a non-base 64 character...'
In trying to find a workaround for FromBase64String(), I tried converting the Base64 string to a Byte[] with GetBytes(), formatting for proper length, converting to char[], then ToBase64CharArray, and finally back to my imageBytes with Convert.FromBase64CharArray. This builds and creates my dll but fails with 'invalid parameter' in Image.FromStream(memoryStream)
public static Image Base64ToImage(string base64String)
{
// Remove the data:image/png;base64
base64String = base64String.Substring(base64String.IndexOf(',') + 1);
base64String = base64String.Trim('\0');
// Convert Base64 String to byte[]
byte[] imageBytes = Convert.FromBase64String(base64String);
using (MemoryStream memoryStream = new MemoryStream(imageBytes, 0, imageBytes.Length))
{
// Convert byte[] to Image
if (imageBytes.Length > 0)
{
using (var image = ((Bitmap)Image.FromStream(memoryStream)).RemoveAlpha())
{
return new Bitmap(image);
}
}
else
return null;
}
}
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.
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.
I am converting Base64 code to image and I am using following way to save and display that image.
var kpin = Base64ToImage(TextBox1.Text);
kpin.Save(#"e:\myim.png");
Image1.ImageUrl = #"e:\myim.png";
and class is
public Image Base64ToImage(string base64String)
{
byte[] imageBytes = Convert.FromBase64String(base64String);
MemoryStream ms = new MemoryStream(imageBytes, 0,
imageBytes.Length);
ms.Write(imageBytes, 0, imageBytes.Length);
Image image = Image.FromStream(ms, true);
return image;
}
and this process working fine but I need an image not to be saved in hard disk. How to display this image directly without saving to hard disk and retrieving back.
Instead of setting the Image1.ImageURL to the path of your image, you can instead do one of several things:
Use an img tag with the Base64 data in it directly - http://www.sweeting.org/mark/blog/2005/07/12/base64-encoded-images-embedded-in-html
Not all browsers support this.
Create an Action or Webform (depending on whether you're using ASP.NET MVC or not) that takes as input whatever you need to either retrieve or generate the Base64 encoded data, and then set the response headers to serve the correct content type (image/png or something) and write the image directly to the Response.OutputStream (or use ContentResult in ASP.NET MVC). Tons of examples via Stackoverflow on how to do either.
-M
Don't bother with the image object at all, and just do it direct:
public void Base64ToResponse(string base64String)
{
Response.ContentType = "text/png"; //or whatever...
byte[] imageBytes = Convert.FromBase64String(base64String);
Response.OutputStream(imageBytes, 0, imageBytes.Length);
}
I am converting images to byte array and storing in a text file using the following code. I am retrieving them successfully as well.
My concern is that the quality of the retrieved image is not up to the expectation. Is there a way to have better conversion to byte array and retrieving? I am not worried about the space conception.
Please share your thoughts.
string plaintextStoringLocation = #"D:\ImageSource\Cha5.txt";
string bmpSourceLocation = #"D:\ImageSource\Cha50.bmp";
////Read image
Image sourceImg = Image.FromFile(bmpSourceLocation);
////Convert to Byte[]
byte[] clearByteArray = ImageToByteArray(sourceImg);
////Store it for future use (in plain text form)
StoreToLocation(clearByteArray, plaintextStoringLocation);
//Read from binary
byte[] retirevedImageBytes = ReadByteArrayFromFile(plaintextStoringLocation);
//Retrieve from Byte[]
Image destinationImg = ByteArrayToImage(retirevedImageBytes);
//Display Image
pictureBox1.Image = destinationImg;
EDIT: And the solution is - use Base64
//Plain Text Storing Location
string plaintextStoringLocation = #"D:\ImageSource\GirlInflower23.txt";
string bmpSourceLocation = #"D:\ImageSource\GirlInflower1.bmp";
////Read image
Image sourceImg = Image.FromFile(bmpSourceLocation);
string base64StringOfIMage = ImageToBase64(sourceImg, ImageFormat.Bmp);
byte[] byteOfString = Convert.FromBase64String(base64StringOfIMage);
StoreToLocation(byteOfString, plaintextStoringLocation);
byte[] retrievedBytesForStrimngForImage = ReadByteArrayFromFile(plaintextStoringLocation);
MemoryStream memStream = new MemoryStream(retrievedBytesForStrimngForImage);
//memStream.Read();
Image retrievedImg = Image.FromStream(memStream);
pictureBox1.Image = retrievedImg;
Yes, it is possible to get completely lossless storage. If you just store it in its original BMP format there will be no problem. I assume you are converting it to text because you want to send it via some protocol where binary characters will be corrupted.
Instead of whatever you are doing, you could consider using Convert.ToBase64String.
I haven't had any problems with this fragment...try it...if you get good results then the problem is in your Image -> byte[] or byte[] -> Image code :)
Image srcImage;
Image destImage;
// load an image
srcImage = Image.FromFile(filename);
// save the image via stream -> byte[]
using(MemoryStream stream = new MemoryStream()){
image.Save(stream, ImageFormat.xxx);
byte[] saveArray = stream.ToArray();
/*..... strore saveArray......*/
}
// rehydrate
byte[] loadArray = /*...get byte array from storage...*/
using(MemoryStream stream = new MemeoryStream(loadArray)){
destImage = Image.FromStream(stream);
}
pictureBox.Image = dstImage;
// don't forget...dispose of any Image/Stream objects