0

我浏览了几页类似的查询,实施了大部分建议,但似乎找不到任何到目前为止有效的方法。希望我没有忽略一些显而易见的事情。

对,所以我使用 AForge.net 来捕获图像。它提供了一个事件,该事件为接收到的每个新帧触发,在我的代码中如下所示:

private void videoSourcePlayer_NewFrame(object sender, ref Bitmap image)
    {
        framesRecieved++;
        try
        {
            if (!stopCapturing)
            {
                if (pictureBox1.Image != null)
                {
                    pictureBox1.Image.Dispose();
                }
                pictureBox1.Image = image.Clone(new Rectangle(0, 0, image.Width, image.Height), image.PixelFormat);
            }

        }
        catch { }
        finally { GC.Collect(); }
    }

只要窗口保持静止,内存使用量就非常稳定,但只要我抓住窗口窗体并开始移动它,内存使用量就会不断上升。我被引导相信它可能与图片框有关的原因是,一旦我将“stopCapturing”布尔值设置为 true,即使我在屏幕周围移动窗口,内存也会停止上升。“stopCapturing”不用于其他任何事情,并且事件继续正常触发,唯一的区别是图片框中显示的图像。我不知道原因,所以任何帮助将不胜感激。

PS:不确定是否相关,但我的工作站有 2 个屏幕。

4

2 回答 2

0

I'm wondering why you're cloning the image at all. It strikes me that you should only allocate a new image when either pictureBox1.Image is null or when the dimensions or pixel format of the image change:

private bool BitmapChanged(Bitmap old, Bitmap new)
{
    return old == null || old.PixelFormat != new.PixelFormat ||
        old.Width != new.Width || old.Height != new.Height;
}

private Bitmap MakeSimilarBitmap(Bitmap source)
{
    Bitmap copy = new Bitmap(source.Width, source.Height, source.PixelFormat);
    return copy;
}

private void DrawOnto(Image im, Bitmap source)
{
    using (Graphics g = Graphics.FromImage(im)) {
        g.DrawImage(source, 0, 0);
    }
}

then when you get a frame, you'll do something like this:

Image im = BitmapChanged(pictureBox1.Image as Bitmap, srcBmp) ?
                          MakeSimilarBitmap(image) : pictureBox1.Image;
DrawOnto(im, srcBmp);
bool same = im == pictureBox1.Image;
if (same)
    pictureBox1.Invalidate();
else {
    Image old = pictureBox1.Image;
    pictureBox1.Image = im;
    old.Dispose();
}
于 2013-03-21T20:28:15.523 回答
0

Bitmap.Clone()做一个浅拷贝,实际字节仍然由调用者拥有,所以这可能会导致各种麻烦。你需要做一个深拷贝。

例如,AForge 方式

Bitmap bmp = AForge.Imaging.Image.Clone(image);

或者 GDI+ 方式(也可以使用 lockbits 等以获得更好的性能):

Bitmap bmp = new Bitmap(image.Width, image.Height, image.PixelFormat);
Graphics g = Graphics.FromImage(bmp);
g.DrawImageUnscaled(image, Point.Empty);
于 2013-03-21T19:46:11.840 回答