Sharon Dorot
Sharon Dorot

Reputation: 542

Displaying live images

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?

Upvotes: 1

Views: 144

Answers (3)

adv12
adv12

Reputation: 8551

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();
    }
}

Upvotes: 2

Felix Castor
Felix Castor

Reputation: 1675

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.

Upvotes: 0

Scott Chamberlain
Scott Chamberlain

Reputation: 127603

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();
}

Upvotes: 1

Related Questions