Bitmap from binary file

  • Thread starter Thread starter gsmith
  • Start date Start date
G

gsmith

Hello,

I am developing a video recording (mjpeg) system which records large
binary files. I need to read the JPEG data from the binary file and
create a bitmap object to be displayed. Unfortunately I cannot find an
efficient way to do this in C#. I need to do this at 10fps+ with 1hour+
data files.

My current approach is read a byte[] from the filestream, then create a
MemoryStream to the created byte[] and then a bitmap from the memory
stream. This seems very excessive and is quite CPU and memory
intensive.

A bitmap constructor like this would be great:

public Bitmap(byte[] data, Int32 startIndex, Int32 length)
OR
public Bitmap(Stream s, Int32 startIndex, Int32 length)

Sadly it looks like the .NET developers weren't thinking about files
like the ones my system will be creating.

Anyone know of an effective/efficient way to load Bitmaps from a binary
file?


Thanks!
Greg
 
A bitmap constructor like this would be great:

public Bitmap(byte[] data, Int32 startIndex, Int32 length)
OR
public Bitmap(Stream s, Int32 startIndex, Int32 length)

Sadly it looks like the .NET developers weren't thinking about files
like the ones my system will be creating.

Anyone know of an effective/efficient way to load Bitmaps from a binary
file?

Well, you can read the file using a stream reader and then use the
static FromStream method on the Bitmap class. Would that work for you?

Chris
 
No it won't because the file contains other data besides the JPEG data.
That's the problem. There is no way to create a bitmap from a portion
of a stream. I think this functionality would be useful for any object
which can be created from a stream, not just a bitmap.

Greg


Chris said:
A bitmap constructor like this would be great:

public Bitmap(byte[] data, Int32 startIndex, Int32 length)
OR
public Bitmap(Stream s, Int32 startIndex, Int32 length)

Sadly it looks like the .NET developers weren't thinking about files
like the ones my system will be creating.

Anyone know of an effective/efficient way to load Bitmaps from a binary
file?

Well, you can read the file using a stream reader and then use the
static FromStream method on the Bitmap class. Would that work for you?

Chris
 
Here is what I am currently doing...

// fileData is a byte[] which contains jpeg data and other data
MemoryStream ms = new (fileData);

MemoryStream imageStream;
byte[] imageBytes;
while(...)
{
// Read the image length and find the start of the image
imageBytes = new byte[imageLength];
imageStream = new MemoryStream(imageBytes);
Bitmap bMap = new Bitmap(imageStream);
}

This just seems so convoluted to me...I wish there was a better
way...grrrrr


Greg

Greg said:
Even better would be one that took an ArraySegment<byte>

Can you post your loop? Just want to see if you are wasting obejcts etc.

Cheers,

Greg Young
MVP - C#
http://codebetter.com/blogs/gregyoung
Hello,

I am developing a video recording (mjpeg) system which records large
binary files. I need to read the JPEG data from the binary file and
create a bitmap object to be displayed. Unfortunately I cannot find an
efficient way to do this in C#. I need to do this at 10fps+ with 1hour+
data files.

My current approach is read a byte[] from the filestream, then create a
MemoryStream to the created byte[] and then a bitmap from the memory
stream. This seems very excessive and is quite CPU and memory
intensive.

A bitmap constructor like this would be great:

public Bitmap(byte[] data, Int32 startIndex, Int32 length)
OR
public Bitmap(Stream s, Int32 startIndex, Int32 length)

Sadly it looks like the .NET developers weren't thinking about files
like the ones my system will be creating.

Anyone know of an effective/efficient way to load Bitmaps from a binary
file?


Thanks!
Greg
 
Could you reuse a buffer isntead of creating one in your inner loop?

Also how big are these buffers?

Cheers,

Greg
Here is what I am currently doing...

// fileData is a byte[] which contains jpeg data and other data
MemoryStream ms = new (fileData);

MemoryStream imageStream;
byte[] imageBytes;
while(...)
{
// Read the image length and find the start of the image
imageBytes = new byte[imageLength];
imageStream = new MemoryStream(imageBytes);
Bitmap bMap = new Bitmap(imageStream);
}

This just seems so convoluted to me...I wish there was a better
way...grrrrr


Greg

Greg said:
Even better would be one that took an ArraySegment<byte>

Can you post your loop? Just want to see if you are wasting obejcts etc.

Cheers,

Greg Young
MVP - C#
http://codebetter.com/blogs/gregyoung
Hello,

I am developing a video recording (mjpeg) system which records large
binary files. I need to read the JPEG data from the binary file and
create a bitmap object to be displayed. Unfortunately I cannot find an
efficient way to do this in C#. I need to do this at 10fps+ with 1hour+
data files.

My current approach is read a byte[] from the filestream, then create a
MemoryStream to the created byte[] and then a bitmap from the memory
stream. This seems very excessive and is quite CPU and memory
intensive.

A bitmap constructor like this would be great:

public Bitmap(byte[] data, Int32 startIndex, Int32 length)
OR
public Bitmap(Stream s, Int32 startIndex, Int32 length)

Sadly it looks like the .NET developers weren't thinking about files
like the ones my system will be creating.

Anyone know of an effective/efficient way to load Bitmaps from a binary
file?


Thanks!
Greg
 
i.e. you could use something like this
http://msdn2.microsoft.com/en-us/library/63z365ty.aspx

this would reduce your memory usage by a huge amount.

Cheers,

Greg
Here is what I am currently doing...

// fileData is a byte[] which contains jpeg data and other data
MemoryStream ms = new (fileData);

MemoryStream imageStream;
byte[] imageBytes;
while(...)
{
// Read the image length and find the start of the image
imageBytes = new byte[imageLength];
imageStream = new MemoryStream(imageBytes);
Bitmap bMap = new Bitmap(imageStream);
}

This just seems so convoluted to me...I wish there was a better
way...grrrrr


Greg

Greg said:
Even better would be one that took an ArraySegment<byte>

Can you post your loop? Just want to see if you are wasting obejcts etc.

Cheers,

Greg Young
MVP - C#
http://codebetter.com/blogs/gregyoung
Hello,

I am developing a video recording (mjpeg) system which records large
binary files. I need to read the JPEG data from the binary file and
create a bitmap object to be displayed. Unfortunately I cannot find an
efficient way to do this in C#. I need to do this at 10fps+ with 1hour+
data files.

My current approach is read a byte[] from the filestream, then create a
MemoryStream to the created byte[] and then a bitmap from the memory
stream. This seems very excessive and is quite CPU and memory
intensive.

A bitmap constructor like this would be great:

public Bitmap(byte[] data, Int32 startIndex, Int32 length)
OR
public Bitmap(Stream s, Int32 startIndex, Int32 length)

Sadly it looks like the .NET developers weren't thinking about files
like the ones my system will be creating.

Anyone know of an effective/efficient way to load Bitmaps from a binary
file?


Thanks!
Greg
 
Greg,

What I don't understand is why you are writing this yourself. Isn't
there a codec for this that you could use to display the file in media
player (or an embedded media player control in your program)?

It seems that you are reinventing the wheel.
 
No it won't because the file contains other data besides the JPEG data.
That's the problem. There is no way to create a bitmap from a portion
of a stream. I think this functionality would be useful for any object
which can be created from a stream, not just a bitmap.

Indeed - so write a wrapper stream which will do the job for you. It
should take the start point of the virtual stream, and either the
length or the end point. You then just need to make sure that you
position the stream accordingly at the start, and delegate calls to
Read, Position etc using the offsets and the lengths.

Of course, you'd have to stipulate that once you'd been given the
stream, nothing else should manipulate it (i.e. reading the wrapped
stream would effectively cause the wrapper stream to be repositioned).
 
Back
Top