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
Related
HalconDotNet.HOperatorSet.ReadImage(out HObject image, srcPath);
//...
//(graphic stuff)
//...
HalconDotNet.HOperatorSet.WriteImage(imagePart, "png", 0, tmpImgPath); // skip these steps
Image = File.ReadAllBytes(path) // skip these steps
This piece of code is executed thousands of times. The last two steps are just there to have a compatibility step in between Halcon and .NET as I dont know how to combine them.
What I need is a way to convert a HImage(HObject) to a byte[], the same way WriteImage() + File.ReadAllBytes(path) would do. This last bit is important as this piece of code generates inputs for image classification models.
As the models are trained with data loaded from disk with File.ReadAllBytes(path) I'm assuming I need to prepare the data in the same way when using the model. When I read a 100x100 color PNG (solid color) with File.ReadAllBytes() I don't get 100x100x3 bytes, but 342, so I'm assuming the data is still compressed, and further assuming that I need to guarantee similar data when using the model.
This question has some overlap with this one but I need a byte[] instead of bitmap and just can't get it to work.
Can you try?
public static byte[] ImageToByte(Image image)
{
using (var stream = new MemoryStream())
{
image.Save(stream, System.Drawing.Imaging.ImageFormat.Png);
return stream.ToArray();
}
}
Or
Image image = Image.FromFile(imagePath);
byte[] byteArr = new byte[] { };
using (var ms = new MemoryStream())
{
image.Save(ms, image.RawFormat);
byteArr = ms.ToArray();
}
For Image you will need System.Drawing
I want to save an image that exist in picture box as a byte array to the database.I am new to programming so please help me to resolve this. Everytime I save my image byte array in the database, it always shows the same byte array. 0x53797374656D2E427974655B5D but this is what I see always in the database. No matter which image I save, it will always saves this code: 0x53797374656D2E427974655B5D. Please help me to resolve this issue.
This is my code
Byte[] imgBytes = null;
ImageConverter imgConverter = new ImageConverter();
imgBytes =
(System.Byte[])imgConverter.ConvertTo(PictureBox1.Image,Type.GetType("System.Byte[]"));
To save an image, use Image.Save
ImageConverter is not for converting image to binary.
var stream = new MemoryStream();
PictureBox1.Image.Save(stream, ImageFormat.Png);
byte[] data = stream.ToArray();
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 have an image on a page, e.g <img id="img3" runat="server" src="image.jpg" width="200" height="200"/> and I'd like to save the image referenced by the src attribute in my database using stored procedure.
I should convert the image to binary first.
Here is what I have so far:
Stream fs = FileUpload1.PostedFile.InputStream;
BinaryReader br = new BinaryReader(fs);
Byte[] bytes = br.ReadBytes((Int32)fs.Length);
cmd.Parameters.AddWithValue("#img", byte);
But the thing is that I don't want to save the uploaded image FileUpload1.PostedFile.InputStream, I want to save the image that I had its src.
Is there a way to put the image src in stream so that I can save it or what is the right way for doing that?
Generally it is not recommended to store images in Database or any other type of files in RDBMS. What is most effective way, to store the file over disk on server, and store that path in your table.
So whenever you need to reference that image/file, then fetch the path from the database, and read the file from disk. This broadly has following two benefits.
Removes the extensive conversion process (from image to binary and
vice-versa).
Helps to read the image directly (soft-read).
Saving an image in the database is not recommanded, but if you insist on saving it in your database you can convert the image to base64, then save the base64 string in your database.
using (Image image = Image.FromStream(FileUpload1.PostedFile.InputStream))
{
using (MemoryStream m = new MemoryStream())
{
image.Save(m, image.RawFormat);
byte[] imageBytes = m.ToArray();
// Convert byte[] to Base64 String
string base64String = Convert.ToBase64String(imageBytes);
//Now save the base64String in your database
}
}
And to convert it back from base64 to an image:
public Image GetImageFromBase64String(string base64String)
{
byte[] bytes = Convert.FromBase64String(base64String);
Image image;
using (MemoryStream ms = new MemoryStream(bytes))
{
image = Image.FromStream(ms);
}
return image;
I combined some code from converting a base 64 string to an image and saving it
and from Convert image path to base64 string .
My goal is to upload and download images using a web service. I understand that in order to do that the images need to be converted to a byte array. However, I’m getting “Unspecified error” when converting a byte array into a BitmapImage.
I’ve create a test rig that converts an image (from a PhotoChooserTask) into a byte array and back again that recreates my problem. The code that does the conversion is listed below with the problem line highlighted.
Any help would be appreciated!
private void PhotoChooserTaskCompleted(object sender, PhotoResult e)
{
if (e.TaskResult == TaskResult.OK)
{
//Display the photo
BitmapImage PhotoBitmap = new BitmapImage();
PhotoBitmap.SetSource(e.ChosenPhoto);
Photo.Source = PhotoBitmap;
//Convert the photo to bytes
Byte[] PhotoBytes = new byte[e.ChosenPhoto.Length];
e.ChosenPhoto.Read(PhotoBytes, 0, PhotoBytes.Length);
//Convert the bytes back to a bitmap
BitmapImage RestoredBitmap = new BitmapImage();
MemoryStream stream = new MemoryStream(PhotoBytes);
BitmapImage image = new BitmapImage();
RestoredBitmap.SetSource(stream); //<------ I get "Unspecified error" on this line
//Display the restored photo
RestoredPhoto.Source = RestoredBitmap;
}
}
The first time you use e.ChosePhoto as source, the stream is read and the Position property is advanced to the end. You can inspect the PhotoBytes array in the debugger to see that after your read operation it actually does not have any content (or check the return value of the Read method to confirm zero bytes are read).
What you need to do is reset that Position to zero before you read from it again:
//Convert the photo to bytes
Byte[] PhotoBytes = new byte[e.ChosenPhoto.Length];
// rewind first
e.ChosenPhoto.Position = 0;
// now succeeds
e.ChosenPhoto.Read(PhotoBytes, 0, PhotoBytes.Length);
I would bet that this is what's happening (comments inline):
//Display the photo
BitmapImage PhotoBitmap = new BitmapImage();
PhotoBitmap.SetSource(e.ChosenPhoto); // This is reading from the stream
Photo.Source = PhotoBitmap;
//Convert the photo to bytes
Byte[] PhotoBytes = new byte[e.ChosenPhoto.Length];
e.ChosenPhoto.Read(PhotoBytes, 0, PhotoBytes.Length); // Fails to read the full stream
// because you already read from it
//Convert the bytes back to a bitmap
BitmapImage RestoredBitmap = new BitmapImage();
MemoryStream stream = new MemoryStream(PhotoBytes); // You're creating a stream that
// doesn't contain the image
BitmapImage image = new BitmapImage();
RestoredBitmap.SetSource(stream); // Fails because your stream is incomplete
Seek to 0 in the stream before you attempt to read from it. And check the return value from the Read call to make sure it matches PhotoBytes.Length.
This:
//Display the photo
BitmapImage PhotoBitmap = new BitmapImage();
PhotoBitmap.SetSource(e.ChosenPhoto);
Photo.Source = PhotoBitmap;
uses the Stream of the e.ChosenPhoto and might not rewind the Position of the Stream.
So when you do this:
Byte[] PhotoBytes = new byte[e.ChosenPhoto.Length];
e.ChosenPhoto.Read(PhotoBytes, 0, PhotoBytes.Length);
you are starting at the end of the stream reading nothing.
Use Seek to reset the Position of the stream.
Did you check out my other post where I already did this?
I had receive a pretty good rating from it.
BitmapImage to byte[] and byte[] to BitmapImage