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. 在内存中进行了一些监控之后,我注意到每次调用getBitmapSourceFromBitmap我的内存每次都会爆炸 100MB。有谁知道为什么会这样?对不起我的英语不好。

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 回答