Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Parameter is not valid error when creating image from byte[] in c#

Tags:

c#

image

I am trying to convert a byte[] to Bitmap in c#. Following is the code:

MemoryStream ms = new MemoryStream(b);
Bitmap bmp = new Bitmap(ms);

It shows the error Parameter is not valid when creating the Bitmap.

byte[] b is coming from a network stream.

But when I write this byte[] to a file, and open this file in any image viewer just works perfectly. Following is code for writing the byte[] to file:

 var fs = new BinaryWriter(new FileStream("tmp.bmp", FileMode.Create, FileAccess.Write));
 fs.Write(b);
 fs.Close();

What am I missing here?

EDIT

Here is my full code that was causing problem

 Socket s = listener.AcceptSocket();
 byte[] b = new byte[imgLen];
 s.Receive(b);
 MemoryStream ms = new MemoryStream(b);
 // now here I am using ms.Seek(0, SeekOrigin.Begin); that fixed my problem.
 Bitmap bmp = new Bitmap(ms);
 pictureBox1.Image = bmp;
 s.Close();

I am using this code on Form_Load event and there is nothing extra. I am just trying to display an Image that is streamed on network. The server is written in Java that is streaming this image.

Hope it clarifies the doubts.

Thanks

like image 707
Vinod Maurya Avatar asked Mar 12 '11 20:03

Vinod Maurya


2 Answers

Okay, just to clarify things a bit... the problem is that new Bitmap(ms) is going to read the data from the stream's current position - if the stream is currently positioned at the end of the data, it's not going to be able to read anything, hence the problem.

The question claims that the code is this:

MemoryStream ms = new MemoryStream(b);
Bitmap bmp = new Bitmap(ms);

In that case there is no requirement to reset the position of the stream, as it will be 0 already. However, I suspect the code is actually more like this:

MemoryStream ms = new MemoryStream();
// Copy data into ms here, e.g. reading from NetworkStream
Bitmap bmp = new Bitmap(ms);

or possibly:

MemoryStream ms = new MemoryStream(b);
// Other code which *reads* from ms, which will change its position,
// before we finally call the constructor:
Bitmap bmp = new Bitmap(ms);

In this case you do need to reset the position, because otherwise the "cursor" of the stream is at the end of the data instead of the start. Personally, however, I prefer using the Position property instead of the Seek method, just for simplicity, so I'd use:

MemoryStream ms = new MemoryStream();
// Copy data into ms here, e.g. reading from NetworkStream

// Rewind the stream ready for reading
ms.Position = 0;
Bitmap bmp = new Bitmap(ms);

It just goes to show how important it is that the sample code in a question is representative of the actual code...

like image 69
Jon Skeet Avatar answered Oct 14 '22 10:10

Jon Skeet


Try like this:

byte[] b = ...
using (var ms = new MemoryStream(b))
using (var bmp = Image.FromStream(ms))
{
    // do something with the bitmap
}
like image 36
Darin Dimitrov Avatar answered Oct 14 '22 10:10

Darin Dimitrov