C#从项目资源中获取图像源会造成内存泄漏

时间:2013-07-28 11:03:57

标签: c# memory-leaks resources bitmapsource

好的,在我的项目资源中我有一些图像(.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时,没有错误,没有警告,图像变化正常。在内存中进行一些监控之后,我注意到每次调用getBitmapSourceFromBitmap我的内存每次都会爆炸100MB。 有谁知道为什么会这样? 抱歉我的英文。

1 个答案:

答案 0 :(得分: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)
    }
}