0

Ok, in my project resources i have some images (.png). Whenever the user clicks on a Button a new image will be shown in an ImageBox. Because all of my images are stored in my project resources i have to get the Image.Source by code. I managed to do it by using a Method like this :

 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;

 }

In my app everything works fine. No errors , no warnings, images change fine every time i push the Button. After some monitoring in the memory , i noticed that every time i call the getBitmapSourceFromBitmap my memory explodes 100MB EVERY TIME. Does anyone have any idea why is this happening? Sorry for my English.

oimitro
  • 1,466
  • 4
  • 14
  • 22

1 Answers1

2

You are using unmanaged resources to create bitmap from your image. GC doesn't takes care of memory allocated to unmanaged resources. You need to dispose of your memory that you are using in that method.

After you have converted your image to bitmap you need to release all the unmanaged resources.

my memory explodes 100MB EVERY TIME

As a general statement if your memory increases by 100MB doesn't means that you have a memory leak. In case of managed resources GC will collect all the memory that is collectible whenever it will feel feasible.

Your Problem: As stated in the MSDN

You are responsible for calling the GDI DeleteObject method to free the memory used by the GDI bitmap object

You need to change your code like this

[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)
    }
}
Ehsan
  • 31,833
  • 6
  • 56
  • 65
  • Perfect. Thank you a lot. After some search i found out that Imaging.CreateBitmapSourceFromHBitmap could cause memory problems if the image is in a format other than .png. After converting all my images in a non transparent .png image(about 9kB per image) everything went smoothly. And your solution works perfect so i will check it as answered , so that anyone else with same problem have a guide. Thnak you again for your answer. – oimitro Jul 28 '13 at 11:53