0

私のプロジェクト リソースには、いくつかの画像 (.png) があります。ユーザーがButton新しい画像をクリックすると、ImageBox. すべての画像がプロジェクト リソースに保存されているため、Image.Sourceコードで取得する必要があります。私はMethodこのようなを使用してそれを行うことができました:

 public void ImageSource()
 {
     Bitmap someImage;
     BitmapSource someImageSource;

     someImage= new Bitmap(Properties.Resources.Image1);
     someImageSource = getBitmapSourceFromBitmap(someImage);
     ImageBox.Source = someImageSource;
 }

 public static BitmapSource getBitmapSourceFromBitmap(Bitmap bmp)
 {  
     BitmapSource returnSource = null;

     try
     {
         returnSource = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(bmp.GetHbitmap(), IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());
     }
     catch { returnSource = null; }

     return returnSource;

 }

私のアプリでは、すべて正常に動作します。エラーも警告もありません。 を押すたびに画像が変化しButtonます。メモリを監視した後、メモリを呼び出すたびに、毎回getBitmapSourceFromBitmap100MBが爆発することに気付きました。なぜこれが起こっているのか誰にも分かりますか?私の英語でごめんなさい。

4

1 に答える 1

2

アンマネージ リソースを使用してイメージからビットマップを作成しています。GC は、アンマネージ リソースに割り当てられたメモリを処理しません。そのメソッドで使用しているメモリを破棄する必要があります。

イメージをビットマップに変換したら、すべてのアンマネージ リソースを解放する必要があります。

私のメモリは毎回 100MB 爆発します

一般的に、メモリが 100MB 増加しても、メモリ リークが発生しているとは限りません。管理されたリソースの場合、GC は実行可能と思われるときはいつでも、収集可能なすべてのメモリを収集します。

あなたの問題:MSDN に記載されているように

GDI の DeleteObject メソッドを呼び出して、GDI ビットマップ オブジェクトが使用するメモリを解放する必要があります。

このようにコードを変更する必要があります

[System.Runtime.InteropServices.DllImport("gdi32.dll")]
public static extern bool DeleteObject(IntPtr hObject);


using (System.Drawing.Bitmap bmp = new System.Drawing.Bitmap(1000, 1000)) {
    IntPtr hBitmap = bmp.GetHbitmap();
    try {
        var source = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(hBitmap, IntPtr.Zero, Int32Rect.Empty, System.Windows.Media.Imaging.BitmapSizeOptions.FromEmptyOptions());
    }
    finally {
        DeleteObject(hBitmap)
    }
}
于 2013-07-28T11:14:29.597 に答える