-
March 3rd, 2012, 07:25 PM
#1
GDI+ Memory Leak?
I keep getting memory leaks from GDI+ and i cant figure out whats doing it. Im trying to make a pixel detection system. I could really use some help finding whatever im doing wrong here >.< Doh!
Here is my first function where it says i ran out of memory.
Code:
public Bitmap capturescreen(Rectangle rect)
{
Size sz = Screen.PrimaryScreen.Bounds.Size;
IntPtr hDesk = GetDesktopWindow();
IntPtr hSrce = GetWindowDC(hDesk);
IntPtr hDest = CreateCompatibleDC(hSrce);
IntPtr hBmp = CreateCompatibleBitmap(hSrce, sz.Width, sz.Height);
IntPtr hOldBmp = SelectObject(hDest, hBmp);
bool b = BitBlt(hDest, 0, 0, rect.Width, rect.Height, hSrce, 0, 0, CopyPixelOperation.SourceCopy | CopyPixelOperation.CaptureBlt);
Bitmap bmp = Bitmap.FromHbitmap(hBmp); <---- says out of memory here
SelectObject(hDest, hOldBmp);
DeleteObject(hBmp);
DeleteObject(hOldBmp);
DeleteDC(hDest);
ReleaseDC(hDesk, hSrce);
return bmp;
}
And here is the pixel search function which uses the above function.
Code:
// P/Invoke declarations
[DllImport("gdi32.dll")]
static extern bool BitBlt(IntPtr hdcDest, int xDest, int yDest, int
wDest, int hDest, IntPtr hdcSource, int xSrc, int ySrc, CopyPixelOperation rop);
[DllImport("user32.dll")]
static extern bool ReleaseDC(IntPtr hWnd, IntPtr hDc);
[DllImport("gdi32.dll")]
static extern IntPtr DeleteDC(IntPtr hDc);
[DllImport("gdi32.dll")]
static extern IntPtr DeleteObject(IntPtr hDc);
[DllImport("gdi32.dll")]
static extern IntPtr CreateCompatibleBitmap(IntPtr hdc, int nWidth, int nHeight);
[DllImport("gdi32.dll")]
static extern IntPtr CreateCompatibleDC(IntPtr hdc);
[DllImport("gdi32.dll")]
static extern IntPtr SelectObject(IntPtr hdc, IntPtr bmp);
[DllImport("user32.dll")]
public static extern IntPtr GetDesktopWindow();
[DllImport("user32.dll")]
public static extern IntPtr GetWindowDC(IntPtr ptr);
public Point PixelSearch(Rectangle rect, int PixelColor, int Shade_Variation)
{
Color Pixel_Color = Color.FromArgb(PixelColor);
Point Pixel_Coords = new Point(-1, -1);
Bitmap RegionIn_Bitmap = capturescreen(rect);
BitmapData RegionIn_BitmapData = RegionIn_Bitmap.LockBits(new Rectangle(0, 0, RegionIn_Bitmap.Width, RegionIn_Bitmap.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
int[] Formatted_Color = new int[3] { Pixel_Color.B, Pixel_Color.G, Pixel_Color.R }; //bgr
unsafe
{
for (int y = 0; y < RegionIn_BitmapData.Height; y++)
{
byte* row = (byte*)RegionIn_BitmapData.Scan0 + (y * RegionIn_BitmapData.Stride);
for (int x = 0; x < RegionIn_BitmapData.Width; x++)
{
if (row[x * 3] >= (Formatted_Color[0] - Shade_Variation) & row[x * 3] <= (Formatted_Color[0] + Shade_Variation)) //blue
{
if (row[(x * 3) + 1] >= (Formatted_Color[1] - Shade_Variation) & row[(x * 3) + 1] <= (Formatted_Color[1] + Shade_Variation)) //green
{
if (row[(x * 3) + 2] >= (Formatted_Color[2] - Shade_Variation) & row[(x * 3) + 2] <= (Formatted_Color[2] + Shade_Variation)) //red
{
Pixel_Coords = new Point(x + rect.X, y + rect.Y);
goto end;
}
}
}
}
}
}
end:
RegionIn_Bitmap.UnlockBits(RegionIn_BitmapData);
return Pixel_Coords;
}
-
March 5th, 2012, 04:47 PM
#2
Re: GDI+ Memory Leak?
I don't see you calling Dispose() on any of your Bitmaps created in PixelSearch(). This is not a "leak" in the classical sense as the memory will be released from the object's finalizer, but it is not deterministic and if you are calling this method a lot you could easily run out of memory.
Second, you why are you using a bitwise AND (&) instead of a logical AND (&&)? That shouldn't even compile in C# as the result is not a boolean...
Third... goto? Why? Just return. You really should be wrapping that in a try/finally as, if an exception is thrown, you will not unlock the bitmap.
Implement those and see if it helps.
If you liked my post go ahead and give me an upvote so that my epee.... ahem, reputation will grow.
Yes; I have a blog too - http://the-angry-gorilla.com/
-
April 20th, 2012, 02:32 PM
#3
Re: GDI+ Memory Leak?
Hmmmm.... I usually use Deleaker for debugging GDI leaks. I keep my brain :P
-
April 25th, 2012, 03:58 PM
#4
Re: GDI+ Memory Leak?
Originally Posted by MastAvalons
Hmmmm.... I usually use Deleaker for debugging GDI leaks. I keep my brain :P
+1 effective tool
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|