我查看了几页类似的查询,实现了大部分建议,但似乎找不到任何有效的方法。希望我不会忽视一些明显的东西。
是的,所以我正在使用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”bool变为true,即使我在窗口周围移动窗口,内存也会停止上升。 “stopCapturing”不用于其他任何事情,并且事件继续正常触发,唯一的区别是图片显示在图片框中。我对原因感到茫然,所以任何帮助都会受到赞赏。
PS:不确定它是否相关,但我的工作站有2个屏幕。
答案 0 :(得分:0)
Bitmap.Clone()
执行浅拷贝,实际字节仍然由调用者拥有,因此这可能会导致各种麻烦。
你需要做一个深层复制。
例如,AForge way:
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);
答案 1 :(得分:0)
我想知道为什么你要克隆图像。令我感到震惊的是,当pictureBox1.Image为null或图像的尺寸或像素格式发生变化时,您应该只分配一个新图像:
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);
}
}
然后当你得到一个框架时,你会做这样的事情:
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();
}