2013-04-09 81 views
2

我正在用C#開發一個應用程序,並且我開發了一個用Aforge相機完成一些內容的庫。其中一點是簡單地捕捉到了什麼是在網絡攝像頭前的圖像,並顯示在一個特定的PictureBox這樣做:AForge相機內存泄漏

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,如果更高,內存泄漏會增加。

計算機配置:

英特爾I5:內存泄漏爲500MB

英特爾I7: NO內存泄漏。

雙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上的發佈模式下,而不是在調試時發生。

NOTE2:我認爲問題自帶FromBimapImage,因爲我嘗試了WindowsForms應用程序而不是一個WPF並沒有內存泄漏......

+0

什麼是'PictureBox.FromBitmapImage(位圖)'方法,它返回什麼? – 2013-04-09 14:22:21

回答

3

AForge owns圖像的字節,你應該做你自己的副本。將框架傳遞給位圖構造函數是不夠的。如果框架無法正確處理位圖,因爲您有參考,則會出現泄漏。

試試這個:

private void NewFrame(object sender, NewFrameEventArgs args) 
{ 
    Bitmap newFrame = AForge.Imaging.Image.Clone(args.Frame); 
    PictureBox.FromBitmapImage(newFrame); 
    newFrame.Dispose(); 
} 
+0

我用這種方式,但我仍然有一些內存泄漏。我意識到,只有當我在Visual Studio 2010上發佈時,內存泄漏才存在。任何想法爲什麼? – Sonhja 2013-04-10 08:10:20

+0

你的解決方案是問題的一部分,但我也不得不'凍結'內存流方法中的'BitmapImage' :)解決! – Sonhja 2013-04-10 15:48:09

2

這對我的作品。

 if (pictureBox1.Image != null) { 
      pictureBox1.Image.Dispose(); 
     } 
     Bitmap bitmap = eventArgs.Frame.Clone() as Bitmap; 
     pictureBox1.Image = bitmap; 
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(); 
    } 
}