releasing resources with IExportBmp

3580
1
03-16-2015 03:43 PM
IainGillies
New Contributor

Hi

I am writing a program to render a map as a in-memory Bitmap that then sends the data to another application.

I've followed the ExportJpg example here.

ArcObjects 10 .NET SDK Help

The problem is the exporter creates a GDI HBitmap.  I want a .Net Bitmap so I'm using Systems.Drawing.Image.FromHbitmap()

Microsoft sdk Image.FromHbitmap Method (IntPtr) (System.Drawing) says that you have to use the gdi32.dll call to DeleteObject() to release the GDI Object manually after using FromHbitmap().

What I am finding is that the GDI handle that is created by FromHBitmap is never released and the program leaks a GDI Object every time the new bmp is exported.

// activeView and exportBmpClass are already setup similar to ExportJPJ example

Int32 hDC = exportBmpClass.StartExporting(); // Creates 1 DC and 1 HBitmap
activeView.Output(hDC, (int)exportBmpClass.Resolution, ref exRect, null, null); //renders activeview to the hDC/ HBitmap

Bitmap bmp = Image.FromHbitmap((IntPtr)exportBmpClass.Bitmap, (IntPtr)exportBmpClass.Palette); // creates 1 HBitmap

DeleteObject((IntPtr)exportBmpClass.Bitmap); // gdi32.dll call does not release a HBitmap!

exportBmpClass.FinishExporting(); // releases 1 DC
exportBmpClass.Cleanup(); //releases 1 HBitmap

// rest of code, do stuff with the .Net bmp ...

Any ideas? 

Thanks

Iain

0 Kudos
1 Reply
IainGillies
New Contributor

OK after several days of painful debugging I've fixed my problem

The problem is not with the Image.FromHBitmap() method it is in the ExportBmpClass.

Int32 hDC = exportBmpClass.StartExporting();
activeView.Output(hDC, (int)exportBmpClass.Resolution, ref exRect, null, null);

// save the handle
int hBmp1 = exportBmpClass.Bitmap;

exportBmpClass.finishExporting();
// save the handle again
int hBmp2 = exportBmpClass.Bitmap;
// output handle values to compare.  they are different!
Console.WriteLine("hBmp1 = " + hBmp +", hBmp2 = " + hBmp2); 

Bitmap bmp = Image.FromHbitmap(bmp1);
// the other handle also would work
//Bitmap bmp = Image.FromHbitmap(bmp2);

exportBmpClass.Cleanup();]

//now both HBitmaps must be deleted
DeleteObject(hBmp1);
DeleteObject(hBmp2);

For some reason the ExportBmpClass is making a copy at the finishExporting() call and looses its first handle.

0 Kudos