Bitmap from binary file

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
 
C

Chris Dunaway

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
 
G

gsmith

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
 
G

gsmith

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
 
G

Greg Young

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
 
G

Greg Young

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
 
N

Nicholas Paldino [.NET/C# MVP]

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.
 
J

Jon Skeet [C# MVP]

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).
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top