2011-10-24 64 views
2

私のWebカメラからの画像を、WebCam_Capture.dllでWPFの画像コントロールにキャプチャします。キャプチャされたすべてのフレームについて、私はwebCam_imageCapturedというイベントを持っています。私はウェブカメラから新しい画像を受け取るたびに呼び出します。このイベントでは、メソッドLoadBitmapを呼び出してhBitmapを取得し、BitmapSourceを受け取って、このキャプチャした画像を画像コントロールに配置します。ここ は、このメソッドのコードです:ビットマップとhBitmapメモリのリーク

[System.Runtime.InteropServices.DllImport("gdi32.dll")] 
public static extern bool DeleteObject(IntPtr handle); 
public BitmapSource bs; 
public IntPtr ip; 
public BitmapSource LoadBitmap(System.Drawing.Bitmap source) 
{ 
    ip = source.GetHbitmap(); 
    bs = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(ip, IntPtr.Zero, System.Windows.Int32Rect.Empty, 
    System.Windows.Media.Imaging.BitmapSizeOptions.FromEmptyOptions()); 
    DeleteObject(ip); 
    return bs; 
} 

そして、ここでは、イベントのコードです:

private void webcam_ImageCaptured(object source, WebcamEventArgs e) 
{ 
    //_frameImage is Image WPF control. 
    _frameImage.Source = LoadBitmap((System.Drawing.Bitmap)e.WebCamImage); 
} 

そして、私はここで、リークを持っています! RAMは1 GBまで、時にはそれ以上の負荷がかかります! DeleteObject(ip)は、呼び出されるたびに動作しません。 RAMが1 GB以上になると、メモリが不足しています。これを解決するには?

+0

不要になったときにビットマップを破棄していますか? –

+0

DeleteObjectメソッドの後に破棄しようとしました。このように: source.Dispose();それは助けにはならなかった。 –

+1

漏れが実際にここにあることは確かですか?それをどうやって決めましたか?任意の種類のプロファイラを使用しましたか?これらのBitmapSourceオブジェクトへの参照が失効している可能性はありますか?あなたはそれを使用した後、なぜあなたのビットマップを処分していないのですか?それは確かに(一時的な)メモリリークです。 BitmapCacheOptions.OnLoadを使用してBitmapSourceを作成し、Bitmapを削除します。 –

答えて

2

プロファイラの助けを借り、あるいはあなたのコードの残りの部分を見なければ、私はほとんど「漏れ」がここにあることを保証することができます

_frameImage.Source = LoadBitmap((System.Drawing.Bitmap)e.WebCamImage); 

方法は確かに非常に迅速に呼び出されているとあなたがされていないことBitmapsDispose()です。 GCはあなたの後にきれいに来る時間を持っておらず、それぞれBitmapでファイナライザを呼び出すので、メモリが足りなくなります。

完了したら、BitmapDispose()と電話する必要があります。 BitmapSourceは、とにかくイメージデータのコピーを作成するので、必要はありません。私はこれをしようとするだろう。もちろん

private void webcam_ImageCaptured(object source, WebcamEventArgs e) 
{ 
    using(Bitmap b = e.WebCamImage) 
    { 
     _frameImage.Source = LoadBitmap((System.Drawing.Bitmap)e.WebCamImage); 
    } 
} 

これは、このイベントハンドラ内のビットマップを処分することは行うには、有効なものであることを前提としていますが、中にBitmapSourceを公開すること(すなわち、他の誰がこのイベントを処理しますか?)代わりにWebCamEventArgsクラスを使用して、他のクライアントが有効であることを確認することができます。Bitmapが有効です。

これはもちろん、APIを使用していると書かれている場合です。そうでない場合は、実際にはコードがBitmapと表示されることはなく、WPFイメージタイプのみを扱うラッパーを作成することもできます。

+0

はい、そうです。このライブラリは内部にリークがあります。それはこのイベントに現れます。ありがとうございました。 –

関連する問題