0

I have an auto-clicker where if you click a button it checks your current screen, the screen it saw when you made the auto-clicker program, compares them, and if they're similar enough it "approves" the set-up. Otherwise it says to adjust your camera angle and warns you that the auto-clicker could fail.

The problem is if you spam the button, "Calibrate" in this case, it will eventually lead to an "Out of memory" exception.

I noticed this when I got mad running it myself, unable to get it to pass, spamming the button... and then the program crashed.

The code that I think is relevant is:

            For Each scr As Screen In Screen.AllScreens
                Wdt += scr.Bounds.Width
            Next
            Dim ScreenSizeTotal As Size = New Size(Wdt, My.Computer.Screen.Bounds.Height)
            Dim ScreenGrab1 As New Bitmap(Wdt, My.Computer.Screen.Bounds.Height)
            Dim g As Graphics = Graphics.FromImage(ScreenGrab1)
            g.CopyFromScreen(New Point(0, 0), New Point(0, 0), ScreenSizeTotal)
            If System.IO.File.Exists(DriveLetter & "RSAutoClicker\" & "TestClick.bmp") = True Then
                My.Computer.FileSystem.DeleteFile(DriveLetter & "RSAutoClicker\" & "TestClick.bmp")
            End If
            ScreenGrab1.Save(DriveLetter & "RSAutoClicker\" & "TestClick.bmp")
            a = New Bitmap(DriveLetter & "RSAutoClicker\" & TestProgram & "\" & TestProgram & "Click1.bmp") 'Out of memory exception occurs on this line
            b = New Bitmap(DriveLetter & "RSAutoClicker\" & "TestClick.bmp")
            Dim ScreenRegion As New Bitmap(b.Width, b.Height, System.Drawing.Imaging.PixelFormat.Format32bppPArgb)
            For y As Integer = My.Settings.VerifyScreenYU To My.Settings.VerifyScreenYD - 1 Step 4
                For x = My.Settings.VerifyScreenXL To My.Settings.VerifyScreenXR - 1 Step 4
                    Dim aColor As Color = a.GetPixel(x, y)
                    Dim bColor As Color = b.GetPixel(x, y)
                    If aColor.ToArgb() = bColor.ToArgb() Then
                        PixelMatchCount += 1
                    End If
                    TotalPixels += 1
                Next
            Next
            a.Dispose()
            b.Dispose()

The stuff about saving/deleting is about the "Calibrate" button and deleting the picture after the check has been done. The YL YR XD & XU is the boundaries of where to check in the left, right, top, and down direction on the screen.

The "Step 4" stuff is because I'm only checking every 4th pixel, otherwise its very intensive operating wise. Every 4 pixels in the X & Y direction seemed to be a good compromise that still gave good results.

I use .Dispose() to throw everything away when it's done. But I think I have misunderstood what .Dispose() is for, because it isn't doing that. I feel that is where the error lies, but I don't know how to fix it.

I could be totally wrong, but any help is appreciated. thank you!

Joshieee
  • 59
  • 11
  • Two things: to speed it up, you can use LockBits (there's information on that in the answers to [Fast work with Bitmaps in C#](https://stackoverflow.com/q/1563038/1115360)). – Andrew Morton Jan 15 '23 at 15:30
  • Second thing: you could set a flag on entry to the code you showed and unset it when the code has finished. If the flag is set then you don't go into that code - so if it was a button click that called the code, you'd simply not do anything. – Andrew Morton Jan 15 '23 at 15:31
  • Rather than calling `Dispose`, you ought to create those objects with a `Using` statement to begin with. They will then be implicitly disposed at the end of the block. You should be doing that with any disposable objects, including the `Graphics` instance. – jmcilhinney Jan 16 '23 at 00:27
  • Disposing is only part of the story though. Disposing an object will release managed and unmanaged resources, but memory is not considered a resource in this context. Unmanaged resources are things like image handles, while managed resources are basically .NET objects that hold other managed or unmanaged resources. The fact that you're disposing your `Images` does not mean that the memory they occupy will be reclaimed. That will only happen when the GC runs. If you are creating lots of large objects in a short period of time, you may need to run the GC explicitly. Research garbage collection. – jmcilhinney Jan 16 '23 at 00:30

0 Answers0