CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 4 of 4
  1. #1
    Join Date
    Mar 2012
    Posts
    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;
            }

  2. #2
    Join Date
    Jun 2008
    Posts
    2,477

    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/

  3. #3
    Join Date
    Nov 2011
    Posts
    21

    Re: GDI+ Memory Leak?

    Hmmmm.... I usually use Deleaker for debugging GDI leaks. I keep my brain :P

  4. #4
    Join Date
    Nov 2011
    Posts
    9

    Re: GDI+ Memory Leak?

    Quote Originally Posted by MastAvalons View Post
    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
  •  





Click Here to Expand Forum to Full Width

Featured