显示实时图像

时间:2014-01-29 16:55:40

标签: c# out-of-memory

我有一个函数返回一个字节数组,其中包含来自摄像头的bmp img live数据(包括标题)。 我将该数组写入MemoryStream对象。 那个对象,我传递给一个Image对象构造函数,它将传递给PictureBox。

tl;博士:

byte[] AoB = GetImage();
MemoryStream ms = new MemoryStream();
ms.Write(AoB, 0, AoB.Length);
pictureBoxImage.Image = Image.FromStream(ms);
ms.Dispose();

所有这些都是在延迟为200 ms(5fps)的定时器中完成的。 它工作正常大约一分钟或2,直到OutOfMemory异常。 出于某种原因,即使我处理了所使用的内存,它也会不断产生新内存。 我也尝试将ms声明为全局并且每次刷新它,但仍然没有。 如何在使用相同的存储空间时流式传输图像?

3 个答案:

答案 0 :(得分:2)

尝试使用Image对象时,请尝试处理它们:

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

答案 1 :(得分:1)

你完全应该在完成它们之后处理旧图像(as adv12 mentioned),但是你也在内存中创建了两个byte[]。第一个是从GetImage()得到的那个,第二个是存储在MemoryStream内的那个,并且由于算法的增长,它可能比源数组大。

而是使用MemoryStream构造函数的this overload来允许您直接传递byte[],而MemoryStream会将该单个数组重用于其内部存储,从而减少记忆要求。

byte[] AoB = GetImage();
using (MemoryStream ms = new MemoryStream(AoB)) {
    Image old = pictureBoxImage.Image;
    pictureBoxImage.Image = Image.FromStream(ms);
    old.Dispose();
}

答案 2 :(得分:0)

尝试设置计时器的AutoReset=false并在最后一次通话结束时手动启动它。

myTimer.AutoReset = false;

在图像分配后开始。

byte[] AoB = GetImage();
MemoryStream ms = new MemoryStream();
ms.Write(AoB, 0, AoB.Length);
pictureBoxImage.Image = Image.FromStream(ms);
ms.Dispose();
myTimer.Start().

计时器有可能超前检索图像。