我正在用C#开发一个应用程序,我开发了一个用Aforge
个摄像头做一些事情的库。其中一点是简单地捕获Web Cam前面的图像并将其显示在特定的PictureBox
上:
camera.NewFrame += NewFrame;
private void NewFrame(object sender, NewFrameEventArgs args)
{
Bitmap newFrame = new Bitmap(args.Frame);
args.Frame.Dispose();
PictureBox.FromBitmapImage(newFrame);
newFrame.Dispose();
newFrame = null;
}
我在这里做的是,我得到每一帧并将其绘制到PictureBox
。
我怀疑是:
在某些计算机中,这种绘画方式会产生非常高的内存泄漏。相机配置为: 640x480 ,如果更高,则内存泄漏会增加。
电脑配置:
Intel i5:内存泄漏到500Mb
Intel i7:没有内存泄漏。
Double coeur(不那么强大):没有那么多内存泄漏。
修改
public static void FromBitmapImage(this Image image, Bitmap bitmap)
{
BitmapImage bitmapImage = new BitmapImage();
using (MemoryStream memoryStream = new MemoryStream())
{
bitmap.Save(memoryStream, ImageFormat.Bmp);
memoryStream.Position = 0;
bitmapImage.BeginInit();
bitmapImage.StreamSource = memoryStream;
bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
bitmapImage.EndInit();
}
image.Source = bitmapImage;
bitmapImage = null;
}
我不明白为什么我在某些电脑上有内存泄漏而其他电脑没有...请问有什么建议吗?
注意:内存泄漏只发生在Visual Studio 2010的发布模式下,而不是在调试时发生。
注2:我认为问题来自于FromBimapImage
,因为我尝试了WindowsForms
应用而不是WPF
应用,并且没有内存泄漏。
答案 0 :(得分:3)
AForge owns图片的字节,您应该制作自己的深副本。将帧传递给Bitmap构造函数是不够的。如果框架无法正确处理位图,因为您有对它的引用,则会发生泄漏。
试试这个:
private void NewFrame(object sender, NewFrameEventArgs args)
{
Bitmap newFrame = AForge.Imaging.Image.Clone(args.Frame);
PictureBox.FromBitmapImage(newFrame);
newFrame.Dispose();
}
答案 1 :(得分:3)
这适合我。
if (pictureBox1.Image != null) {
pictureBox1.Image.Dispose();
}
Bitmap bitmap = eventArgs.Frame.Clone() as Bitmap;
pictureBox1.Image = bitmap;
答案 2 :(得分:0)
在分配新图片之前处理图片框图像有助于防止内存泄漏,但在调整图片框大小时会出现错误。可能问题是由于过早处理图像。它对我有用的是将旧图像保留在队列中,并以5张图像的延迟处理它们。这将使图片框有足够的时间赶上来。
private Queue<Image> _oldImages = new Queue<Image>();
...
if (pictureBox1.Image != null)
{
_oldImages.Enqueue(pictureBox1.Image);
if (_oldImages.Count > 5)
{
var oldest = _oldImages.Dequeue();
oldest.Dispose();
}
}