好的,在我的项目资源中我有一些图像(.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。
有谁知道为什么会这样?
抱歉我的英文。
答案 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)
}
}