I try converting image data from the database which is already in byte[] back to the image and I'm getting "invalid parameter error" using Image.FileStream.
Please, can anyone help me out with this?
I've tried working around the code using various methods and the last one is below in my code.
byte[] data = validaccount.FingerPrint;
try
{
using (MemoryStream strm = new MemoryStream())
{
strm.Write(data, 0, data.Length);
strm.Position = 0;
System.Drawing.Image img = System.Drawing.Image.FromStream(strm);
BitmapImage bi = new BitmapImage();
bi.BeginInit();
MemoryStream ms = new MemoryStream();
img.Save(ms, System.Drawing.Imaging.ImageFormat.Bmp);
ms.Seek(0, SeekOrigin.Begin);
bi.StreamSource = ms;
bi.EndInit();
}
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
The code is supposed to convert the byte[] into an image.
According to the docs, Image.FromStream(stream) will throw an argument exception if "The stream does not have a valid image format". Have you verified the data is actually correct? If so, what type of image is it?
You're misusing your streams. You only need 1 memory stream and it has a constructor that takes a byte array (no need to write the bytes yourself). Be sure to wrap it in a using block (like you did for your first stream).
You may not want to use BitmapImage - that's for xaml/wpf apps. You probably want System.Drawing.Bitmap which inherits/extends System.Drawing.Image. Additionally, Bitmap has a constructor which takes a stream - no need to use FromStream.
Finally, Image (and hence Bitmap since Bitmap inherits Image) implements IDisposable, so you should also wrap it in a using block.
P.S. This is a duplicate question.
Though its not memory stream, this method has worked for me and if you browse SO for your question, some times MS does not work.
using System.Drawing;
var converterdImage = (Bitmap)((new ImageConverter()).ConvertFrom(byteArray));
Byte Array to Image Conversion
Related
I have a function that returns an array of bytes containing the data of a bmp img live from a camera (including header).
I write that array in to a MemoryStream object.
That object, I pass to a Image object constructor, which will be passed to a PictureBox.
tl;dr:
byte[] AoB = GetImage();
MemoryStream ms = new MemoryStream();
ms.Write(AoB, 0, AoB.Length);
pictureBoxImage.Image = Image.FromStream(ms);
ms.Dispose();
All of this is done in a timer with a delay of 200 ms (5fps).
It works fine for about a minute or 2 until OutOfMemory exception.
For some reason, even though I dispose of the memory used, it keeps generating new one.
I've also tried to declare ms as global and flush it every time, still no go.
How can I stream the images while using the same memory space?
Try disposing the Image objects when you're done with them as well:
byte[] AoB = GetImage();
using (MemoryStream ms = new MemoryStream()) {
ms.Write(AoB, 0, AoB.Length);
Image old = pictureBoxImage.Image;
pictureBoxImage.Image = Image.FromStream(ms);
if (old != null) {
old.Dispose();
}
}
You definitely should dispose the old images when you are done with them (as adv12 mentioned), however you are also creating two byte[]s in memory. The first one is the one you get from GetImage() the second one is the one stored inside the MemoryStream and that one could be larger than your source array due to its growing algorithms.
Instead use this overload of the MemoryStream constructor to allow you to pass the byte[] directly in and the MemoryStream will reuse that single array for its internal store, reducing the memory requirement.
byte[] AoB = GetImage();
using (MemoryStream ms = new MemoryStream(AoB)) {
Image old = pictureBoxImage.Image;
pictureBoxImage.Image = Image.FromStream(ms);
old.Dispose();
}
Try setting your timer's AutoReset=false and manually starting it over at the end of the last call.
myTimer.AutoReset = false;
Start after image assignment.
byte[] AoB = GetImage();
MemoryStream ms = new MemoryStream();
ms.Write(AoB, 0, AoB.Length);
pictureBoxImage.Image = Image.FromStream(ms);
ms.Dispose();
myTimer.Start().
The timer has the potential to get ahead of the retrieval of the images.
I'm using this function to convert base64 to image.
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);
//Image image = Image.FromStream(ms, true);
Image image = Image.FromStream(ms,true,true);
return image;
}
}
but it is not working. please help me.
I don't thik the ms write call is needed here.
using (var ms = new MemoryStream(imageBytes, 0,imageBytes.Length))
{
// Convert byte[] to Image
ms.Write(imageBytes, 0, imageBytes.Length);
Your are efectively constructing the stream from your byteArray so the ms.Write call will append the data twice in the stream. This might cause issues for your Image object. Either use the default constructor for the stream or delete the Write and test again.
Edit:
Zey deleted his answer but i think he had a good point in there. You might consider dropping the using block as well. My memory might fail me but i think Image objects need the source stream to be kept open. Dispose the Image object when not needed anymore.
I'm having some difficulty saving a stream of bytes from an image (in this case, a jpg) to a System.IO.MemoryStream object. The goal is to save the System.Drawing.Image to a MemoryStream, and then use the MemoryStream to write the image to an array of bytes (I ultimately need to insert it into a database). However, inspecting the variable data after the MemoryStream is closed shows that all of the bytes are zero... I'm pretty stumped and not sure where I'm doing wrong...
using (Image image = Image.FromFile(filename))
{
byte[] data;
using (MemoryStream m = new MemoryStream())
{
image.Save(m, image.RawFormat);
data = new byte[m.Length];
m.Write(data, 0, data.Length);
}
// Inspecting data here shows the array to be filled with zeros...
}
Any insights will be much appreciated!
To load data from a stream into an array, you read, not write (and you would need to rewind). But, more simply in this case, ToArray():
using (MemoryStream m = new MemoryStream())
{
image.Save(m, image.RawFormat);
data = m.ToArray();
}
If the purpose is to save the image bytes to a database, you could simply do:
byte[] imgData = System.IO.File.ReadAllBytes(#"path/to/image.extension");
And then plug in your database logic to save the bytes.
I found for another reason this article some seconds ago, maybe you will find it useful:
http://www.codeproject.com/KB/recipes/ImageConverter.aspx
Basically I don't understand why you try to write an empty array over a memory stream that has an image. Is that your way to clean the image?
If that's not the case, read what you have written in your memorystream with ToArray method and assign it to your byte array
And that's all
Try this way, it works for me
MemoryStream ms = new MemoryStream();
Bitmap bmp = new Bitmap(panel1.Width, panel1.Height);
panel1.DrawToBitmap(bmp, panel1.Bounds);
bmp.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
byte[] Pic_arr = new byte[ms.Length];
ms.Position = 0;
ms.Read(Pic_arr, 0, Pic_arr.Length);
ms.Close();
Well instead of a Image control, I used a Panel Control.
Hey, I am trying to load an Image control from a byte array, I've tried multiple solutions found online (particularly this site) but nothing seems to work.
My main goal was to obtain an ImageSource from the byte array and return it from a converter.
I've tried:
BitmapImage bi = new BitmapImage();
bi.BeginInit();
bi.StreamSource = new MemoryStream(lBytes);
bi.EndInit();
But this fails with:
NotSupportedException
No imaging component suitable to complete this operation was found.
Also tried first loading a Bitmap and from there try to get the ImageSource.
using (MemoryStream lMem = new MemoryStream(lBytes))
{
TypeConverter tc = TypeDescriptor.GetConverter(typeof(System.Drawing.Bitmap));
System.Drawing.Bitmap b = (System.Drawing.Bitmap)tc.ConvertFrom(lBytes);
lResult = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(
b.GetHbitmap(),
IntPtr.Zero,
System.Windows.Int32Rect.Empty,
BitmapSizeOptions.FromEmptyOptions());
b.Dispose();
}
But this fails on the ConvertFrom with "Parameter is not valid."
All of this when loading a valid PNG file in my filesystem.
I am running out of ideas, any clue?
Thanks.
Edit:
Alright, the problem was my way of loading the file...
I was using
using (FileStream lFileStream = new FileStream(pFilePath, FileMode.Open))
{
using (StreamReader lReader = new StreamReader(lFileStream))
{
BinaryFormatter bf = new BinaryFormatter();
using (MemoryStream ms = new MemoryStream())
{
string lString = lReader.ReadToEnd();
bf.Serialize(ms, lString);
ms.Seek(0, 0);
lImage = ms.ToArray();
}
lResult = new Graphic(lImage);
}
}
But then read that I could use:
lImage = File.ReadAllBytes(pFilePath);
And that's it.
Thank you.
First solution works correctly but I think your problem is about how to read array byte not how to convert the array to bitmap.
I've used that solution many times. The difference between my solution and your solution is how to read the file and convert it to an array.
I simply use:
System.IO.File.ReadAllBytes(filepath)
I have a byte[] that is represented by an Image. I am downloading this Image via a WebClient. When the WebClient has downloaded the picture and I reference it using its URL, I get a byte[]. My question is, how do I load a byte[] into an Image element in WPF? Thank you.
Note: This is complementary to the question I asked here: Generate Image at Runtime. I cannot seem to get that approach to work, so I am trying a different approach.
Create a BitmapImage from the MemoryStream as below:
MemoryStream byteStream = new MemoryStream(bytes);
BitmapImage image = new BitmapImage();
image.BeginInit();
image.StreamSource = byteStream;
image.EndInit();
And in XAML you can create an Image control and set the above image as the Source property.
You can use a BitmapImage, and sets its StreamSource to a stream containing the binary data. If you want to make a stream from a byte[], use a MemoryStream:
MemoryStream stream = new MemoryStream(bytes);
In .Net framework 4.0
using System.Drawing;
using System.Web;
private Image GetImageFile(HttpPostedFileBase postedFile)
{
if (postedFile == null) return null;
return Image.FromStream(postedFile.InputStream);
}
One way that I figured out how to do it so that it was both fast and thread safe was the following:
var imgBytes = value as byte[];
if (imgBytes == null)
return null;
using (var stream = new MemoryStream(imgBytes))
return BitmapFrame.Create(stream,BitmapCreateOptions.None, BitmapCacheOption.OnLoad);
I threw that into a converter for my WPF application after running the images as Varbinary from the DB.