1

I'm trying to get all pixels in a 382x336 px area of my screen, detect certain colors and click the last detected one of them (for a game).

My problem is that my scan takes a huge amount of time to cover that area, making it impossible for my AI to keep up with the game.

Are there better methods to achieve my goal? Or is there a way I could optimize my code to run faster?

Main code:

Dim LFE, LNE As Point
            For YI As Integer = 264 To 600 Step 1
                P.Y = YI
                LFE = New Point(0, 0)
                LNE = New Point(0, 0)
                For XI As Integer = 493 To 875 Step 1
                    P.X = XI
                    If GetPoint(P) = "ffef3031" OrElse GetPoint(P) = "fff0d381" OrElse GetPoint(P) = "ff19a3ff" OrElse GetPoint(P) = "ff795f14" Then
                        LNE = P
                    ElseIf GetPoint(P) = "ffee1600" Then
                        LFE = P
                    End If
                Next
            Next
            If LFE = New Point(0, 0) Then
                If Not LNE = New Point(0, 0) Then
                    Cursor.Position = LNE
                End If
            Else
                Cursor.Position = LFE
End If

GetPoint function:

Function GetPoint(ByVal Pnt As Point) As String
        Dim a As New Drawing.Bitmap(1, 1)
        Dim b As System.Drawing.Graphics = System.Drawing.Graphics.FromImage(a)
        b.CopyFromScreen(New Drawing.Point(MousePosition.X, MousePosition.Y), New Drawing.Point(0, 0), a.Size)
        Dim c As Drawing.Color = a.GetPixel(0, 0)
        PictureBox1.BackColor = c
        Return PictureBox1.BackColor.Name
End Function
Jørgen R
  • 9,179
  • 7
  • 36
  • 56
Remon Ramy
  • 167
  • 1
  • 11
  • 3
    my bet is that `GetPixel`,`SetPixel` is your problem they are painfully slow GDI operations use `ScanLine[]` instead see [GDI Bitmap section](http://stackoverflow.com/a/21699076/2521214). I do not code in VB nor .Net but the GDI encapsulation should be very similar if not the same. Another option but still slower than `ScanLine[]` from what I heard is the `LockBits` but never use that. – Spektre Jun 13 '15 at 06:39
  • Interesting, I'll check it out. – Remon Ramy Jun 13 '15 at 06:42
  • 1
    the Get/SetPixel on GDI performs too many checks and transformations on each call ... ScanLine[] just once per whole line and if you store the pointers to your array then only once per resize/line and then access to it is as access to any other Array in the program ... – Spektre Jun 13 '15 at 06:45
  • 1
    In addition, you're calling GetPoint four times in that conditional. Pull it out into its own variable and reuse it. – Jerry Federspiel Aug 05 '15 at 17:10
  • 1
    Also, you are currently representing the colors of interest as strings and you're making GetPoint return strings to deal with this. Instead, you can represent the colors of interest with Color structs, have GetPoint return a Color struct, and compare those with `color1 == color2` or `color1.ToArgb() == color2.ToArgb()`. – Jerry Federspiel Aug 05 '15 at 18:05
  • 1
    Also, instead of scanning over the whole area and grabbing the last detected pixel of the target color, why not scan backwards and grab the first detected pixel? The more common the target colors are, the bigger a win that would be. – Jerry Federspiel Aug 05 '15 at 18:53

0 Answers0