Farbe in einem bestimmten Feld erkennen (nicht auf einzelne Pixel bezogen)

  • Hi,

    dies ist mein erster Beitrag in diesem Forum. Ich glaube ich habe endlich gefunden, wonach ich gesucht habe :) Ich suche eine Lösung für folgende Situation:

    In einer Tablette (grau hinterlegt) steht ein Wert. Dieser Wert ist entweder in rot oder in blau geschrieben. Ich benötige ein Skript, welches die Farben (abgesehen von dem grauen Hintergrund der Tabellenzelle) ständig in einer Schleife "scannt" und sobald die blaue Schrift einen Mausklick ausübt.

    Ich habe dann dieses Thema im Forum gefunden, woran man sich orientieren kann:

    [ gelöst ] Starthilfe Pixelgetcolor


    In diesem Thema geht es aber um die Farbanalyse eines einzelnen Bildpunktes. Das wäre in meiner Situation zwar auch möglich, aber es könnte schon schwierig werden genau den punkt zu treffen, auf dem die Schrift liegt. Gibt es eine Möglichkeit ein bestimmtes Feld überprüfen zu lassen?


    Würde mich über eure Hilfe sehr freuen.

    Danke :)

    • Offizieller Beitrag

    Auch wenn es hier nicht direkt durchklingt, riecht es doch stark nach Spiele-Bot (Bestand von irgendetwas unter Level -- Nachfüllen/ Nachladen erforderlich).
    Insofern aktiviere ich zwar den Thread, stelle es aber frei darauf überhaupt zu antworten. Sollte sich meine Vermutung bestätigen, wird selbstredend gelöscht.

  • Ich kann dir versichern, es geht nicht um Spiele. Ich benötige soetwas für eine Tabelle. Ich habe eben von der "pixelsearch" funktion erfahren. Das klingt stark nach dem, was ich suche.


    Als erstes habe ich die Koordinaten rausgeschrieben: Gescannt soll das Feld von 2486/347 (oben links) bis 2499/365 (unten rechts). Gesuchte Farbe ist #0000FF (blau). Wenn diese Farbe gefunden wird, soll ein Maus-Klick bei den Koordinaten 2513/352 und danach bei 2513/373 ausgelöst werden.

    Meine Erfahrung im Schreiben solcher Skripte ist leider stark begrenzt. Ich muss mir hier und da was zusammen sammeln. Ich habe nun als erstes die Funktion "Pixelsearch" gefunden. Das Beispiel lautet wie folgt:

    Code
    ; Findet ein rotes Pixel im Rechteck 0,0-200,300. 
    $coord = PixelSearch( 0, 0, 200, 300, 0xFF0000 ) 
    If Not @error Then 
    MsgBox(0, "Die Koordinaten X und Y lauten:", $coord[0] & "," & $coord[1]) 
    EndIf


    Sieht soweit noch logisch für mich aus. Wenn ich das richtig verstehe, sollte ein Nachricht-Fenster erscheinen, welches die Koordinaten angibt, in denen die gesuchte Farbe gefunden wurde. Ich habe das mal anhand einer einfachen roten Fläche getestet. Da passierte leider gar nichts. Muss man denn allgemein noch irgendwas davor schreiben? Tut mir leid, dass ich so blöde Fragen stelle, aber ich bin ziemlich unerfahren. :S


    EDIT 13:45: Hab mich mal dran versucht ....

    Code
    $coord = PixelSearch( 2486, 347, 2499, 356, 0x0000FF ) ;  zu überprüfendes Feld
       While 1
       If $coord = 0x0000FF Then
       MouseClick ("left" [, 2513, 352 [, 1 [, 0]]] )
       MouseClick ("left" [, 2513, 373 [, 1 [, 10]]] )
       ExitLoop
       EndIf

    Keine Ahung, ob ich damit richtig liege oder nich. Funktionieren tuts jedefalls nicht. hmm.

    Einmal editiert, zuletzt von Pjaanoo (17. Juni 2012 um 13:46)

  • So, erstmal zu diesem code hier:

    [autoit]

    $coord = PixelSearch( 2486, 347, 2499, 356, 0x0000FF ) ; zu überprüfendes Feld
    While 1
    If $coord = 0x0000FF Then
    MouseClick ("left" [, 2513, 352 [, 1 [, 0]]] )
    MouseClick ("left" [, 2513, 373 [, 1 [, 10]]] )
    ExitLoop
    EndIf

    [/autoit]

    in Zeile 2 hast du ja eine While schleife. Aber diese schließt nirgendswo ab. Es fehlt WEnd / Der ExitLoop ist um die schleife zu verlassen. aber es nützt dir nichts wenn die schleife nicht abgeschlossen ist

    2. Wenn du die schleife sowieso verlassen willst, nachdem die beiden klicks durchgeführt wurden. kannst du auch die schleife auslassen. :)

    Also ist der code momentan so:

    [autoit]

    $coord = PixelSearch( 2486, 347, 2499, 356, 0x0000FF ) ; zu überprüfendes Feld
    If $coord = 0x0000FF Then
    MouseClick ("left" [, 2513, 352 [, 1 [, 0]]] )
    MouseClick ("left" [, 2513, 373 [, 1 [, 10]]] )
    EndIf

    [/autoit]

    demweiteren:
    MouseClick ("left" [, 2513, 373 [, 1 [, 10]]] )

    Diese Klammern >> [ ] die brauchen da nicht rein, es reicht wenn ein komma da steht :) ^^

    Folgendes: die daten die in den Eckigen klammern steht, die musst du NICHT angeben. Dies ist nur um das ein bischen genauer zu definieren. wenn du es also so machen willst. musst du einfach nur ein Komma einsetzen.

    [autoit]

    $coord = PixelSearch( 2486, 347, 2499, 356, 0x0000FF ) ; zu überprüfendes Feld
    If $coord = 0x0000FF Then
    MouseClick ("left", 2513, 352, 1, 0)
    MouseClick ("left", 2513, 373, 1, 10)
    EndIf

    [/autoit]

    So, nun kann es sein das es die Farbe nicht findet ^^ also kannst du noch ne msgbox erscheinen lassen wenn die farbe nicht gefunden wurde.
    Hier ist der ganze code auskommentiert :)

    [autoit]

    $coord = PixelSearch( 2486, 347, 2499, 356, 0x0000FF ) ;Das ist ja jetzt das Feld, was überprüft werden soll.

    [/autoit][autoit][/autoit][autoit]

    If $coord = 0x0000FF Then ;Wenn $coord = Die gesuchte Farbe ist, werden die Befehle ausgefürhrt
    MouseClick ("left", 2513, 352, 1, 0) ;Ein Linksklick an der entsprechenden stelle.
    MouseClick ("left", 2513, 373, 1, 10) ;Ein Linksklick an einer anderen definierten stelle ^^
    EndIf ;Dies schließt das ganze ab. Das bedeutetet wenn die Farbe nicht gefunden wurde, wird alles zwischen If und EndIf übersprungen.

    [/autoit][autoit][/autoit][autoit]

    If $coord <> 0x0000FF Then ;Das <> bedeutet das es ungleich ist. Also es wird nur ausgeführt wenn die Farbe NICHT 0x0000FF ist.
    MsgBox(0, "Fenstertitel", "Die Farbe konnte nicht gefunden werden!") ;Das ist dann eine Nachrichtenbox, die ausgegeben wird wenn es nicht die farbe ist.
    EndIf ;Das weißt du ja ^^

    [/autoit][autoit][/autoit][autoit]

    ;Weiteres findest du in der hilfe :p wenn du noch fragen hast, schreiben :D]

    [/autoit]

    3 Mal editiert, zuletzt von Yjuq (17. Juni 2012 um 14:33)

    • Offizieller Beitrag

    die daten die in den Eckigen klammern steht, die musst du NICHT angeben. Dies ist nur um das ein bischen genauer zu definieren.


    Nein, eckige Klammern geben an, dass diese Funktionsparameter optional und mit Standardwerten vorbelegt sind.

  • Hey :)

    Danke für deine Hilfe. Das sieht ja schon mal sehr gut aus. Wie gesagt, das sind meine ersten "Gehversuche".

    Wenn ich mir diesen Teil deines Vorschlags anschaue:

    Code
    If $coord <> 0x0000FF Then ;Das <> bedeutet das es ungleich ist. Also es wird nur ausgeführt wenn die Farbe NICHT 0x0000FF ist.
       MsgBox(0, "Fenstertitel", "Die Farbe konnte nicht gefunden werden!") ;Das ist dann eine Nachrichtenbox, die ausgegeben wird wenn es nicht die farbe ist.
    EndIf ;Das weißt du ja ^^

    ... sehe ich, dass eine Nachrichtenbox kommt, wenn die Farbe nicht kommt. Die Farbe kommt aber ganz sicher , ist nur eine Frage der Zeit ;)

    Kann ich also an dieser Stelle auch wieder "zurückspringen", damit das Feld wieder gescannt wird - solange bis die Farbe auftaucht? Desweiteren wäre es auch sinnvoll, dass das Feld wieder nach der Farbe "durchsucht" wird, nachdem es gerade die Mausklicks ausgeführt hat. Sprich eine endlos-Schleife.

    > Farbe entdeckt? Nein = Weiter suchen, bis sie gefunden wurde / Ja = Mausklicks ausführen und wieder zurück in die Such-Schleife.


    Das ganze hat sich nun auf eine Zeile der Tabelle bezogen. Was, wenn ich das selbe für eine zweite Zeile erstellen möchte? In dieser wären dann andere Koordinaten für das Feld und die Mausklicks definiert, aber der Ablauf wäre grundsätzlich der selbe. Wie könnte man realisieren, Das diese verschiedenen Felder ständig kontrolliert werden und die aktion dann unabhängig von einander ausgeführt wird? Sprich, wenn gleichzeitig in beiden Feldern die gesuchte Farbe erscheint, dass das Skript dann nur eins (das erste halt) der Felder und dessen Funktion ausführt? Man müsste die irgendwie "nacheinander schalten", oder?


    Und eine dritte, allgemeine Frage hätte ich noch:

    Woran sehe ich denn, dass das Skript läuft?

    Denn so wie ich es mir vorgestellt habe, läuft es als endlos-rotation. (vielleicht wäre es ganz sinnvoll eine Taste zu belegen, die das Skript beendet.


    Ich hoffe, ich verlange hier nicht zu viel :S

    Ich weiss deine/eure Hilfe zu schätzen :)

  • Ich nochmal. Ich habe das Skript mal getestet und ich komme nun zu dem ergebnis, dass ich immer die Fehlermeldung bekomme, dass die Farbe nicht gefunden worde.

    Dabei habe ich die Koordinaten geändert und auf meinen 2. Bildschirm (daher die weiten Koordinaten) einfach eine große weisse Fläche gelegt,

    ich habe dann natürlich auch nach der Farbe #FFFFFF gesucht. Ich bekomm aber immer die Fehlermeldung, dass die Farbe nicht vorhanden sei. Hmmm.

  • Wenn du willst, dass das script permament so ausgefürht wird, fügst du einfach eine while schleife ein:

    [autoit]

    $coord = PixelSearch( 2486, 347, 2499, 356, 0x0000FF )

    [/autoit][autoit][/autoit][autoit]

    While 1 ;Beginn der Schleife
    If $coord = 0x0000FF Then
    MouseClick ("left", 2513, 352, 1, 0)
    MouseClick ("left", 2513, 373, 1, 10)
    EndIf
    WEnd ;Ende der Schleife

    [/autoit]

    Wenn du das ganze script auf Tastendruck beenden willst, sollte dir die Funktion HotKeySet helfen.

    Hier mal um das ganze Script zu beenden:

    [autoit]

    HotKeySet("{ESC}", "_Ende") ;Wenn man die Esc Taste drückt, wird die Funktion _Ende aufgerufen

    [/autoit][autoit][/autoit][autoit]

    $coord = PixelSearch( 2486, 347, 2499, 356, 0x0000FF )

    [/autoit][autoit][/autoit][autoit]

    While 1
    If $coord = 0x0000FF Then
    MouseClick ("left", 2513, 352, 1, 0)
    MouseClick ("left", 2513, 373, 1, 10)
    EndIf
    WEnd

    [/autoit][autoit][/autoit][autoit]

    Func _Ende() ;Das ist die Funktion _Ende
    Exit ;Das beendet den Script
    EndFunc ;Ende der Funktion

    [/autoit]

    Jedesmal wenn ein Script gestartet wurde, kommt unten rechts ein kleines Icon in der Taskleiste. Aber dies kann man auch Ausschalten. Am sichersten ist es einfach am Anfang eine MsgBox anzeigen zu lassen, die angibt dass das Script gestartet wurde.

    [autoit]

    MsgBox(0, "", "Script wurde gestartet!", 5) ;Es kommt eine Nachricht, die sich nach 5 Sekunden Automatisch schließt.

    [/autoit][autoit][/autoit][autoit]

    HotKeySet("{ESC}", "_Ende")

    [/autoit][autoit][/autoit][autoit]

    $coord = PixelSearch( 2486, 347, 2499, 356, 0x0000FF )

    [/autoit][autoit][/autoit][autoit]

    While 1
    If $coord = 0x0000FF Then
    MouseClick ("left", 2513, 352, 1, 0)
    MouseClick ("left", 2513, 373, 1, 10)
    EndIf
    WEnd

    [/autoit][autoit][/autoit][autoit]

    Func _Ende()
    Exit
    EndFunc

    [/autoit]
  • Was ich noch vergessen habe:

    Soweit ich weiß gibt die Funktion dann das erste gefundene Pixel an. Also würde sich zb. der erste Pixel dieser farbe (Von oben nach unten / Links nach rechts) an position 155x256 befinden, dann wird auch die position zurück gegeben.

    Soweit ich verstanden habe: Du willst das es genau darauf klickt, wo die farbe gefunden wurde, oder?

    PS: ich benutze diese Funktion sogut wie nie, also berichtigt mich pls wenn ich falsch liege ^^

  • Danke für die Antwort :)


    Ne, ich möchte, dass die Klicks (beide an verschienenen Koordinaten) an einer ganz anderen Stelle als dem Suchfeld stattfinden. Das Suchfeld soll nur als Signalgeber dienen.

  • Also ich hätte es so gemacht:

    Wenn du willst das das Skript endlos Läuft:

    [autoit]


    MsgBox(0, "", "Script wurde gestartet!", 5) ;Es kommt eine Nachricht, die sich nach 5 Sekunden Automatisch schließt.

    [/autoit][autoit][/autoit][autoit]

    HotKeySet("{ESC}", "_Ende") ;Sobald Escape gedrückt wird wird die _Ende Funktion aufgerufen

    [/autoit][autoit][/autoit][autoit]

    While Sleep(50)
    $coord = PixelSearch( 2486, 347, 2499, 356, 0x0000FF ) ; durch While schleife sucht er ständig nach der Farbe

    [/autoit][autoit][/autoit][autoit]

    If $coord = 0x0000FF Then ; Sobald er die Farbe gefunden hat macht er die Mausklicks und sucht dann weiter nach einer Farbe
    MouseClick ("left", 2513, 352, 1, 0)
    MouseClick ("left", 2513, 373, 1, 10)
    ;ElseIf $coord <> 0x0000FF Then ; Wenn er die Farbe nicht geunden hat dann kommt eine Msgbox (die Würde ich aber Persönlich weglassen weil sonst wirst du mit MsgBoxen zugeballert
    ; MsgBox(64,"Fenstertitel","Farbe wurde nicht gefunden!")
    EndIf
    WEnd

    [/autoit][autoit][/autoit][autoit]

    Func _Ende()
    Exit ; Hier wird das Skript Beendet
    EndFunc

    [/autoit]
  • Hi danke,

    also ich hab das jetzt mit Hilfe von Make-Grafik so gemacht. Und es funktionert auch so, wie ich es mir vorstelle. Allerdings bekomme ich eine Fehlermeldung. Dazu mehr nach dem Code :)



    Ich konnte das Script einmal durchlaufen lassen. Die Funktionen wurden richtig aufgeführt. Dann kam ein PopUp mit der Meldung:

    Zitat


    Line 5 (File:"C:\\blablabla"):

    $color = PixelGetColor($coord[0], $coord[1])

    §color = PixelGetColor($coord^ ERROR

    Error: Subscript used with non-Array variable.

    Sagt das jemandem was?! 8|

  • Ich weis ja nicht, aber wenn man auch nur ein kleines bisschen Englisch kann, dann sollte man die Fehlermeldungen von Autoit doch verstehen können... ?(

    Zitat

    Line 5 (File:"C:\\blablabla"):

    $color = PixelGetColor($coord[0], $coord[1])

    §color = PixelGetColor($coord^ ERROR

    Error: Subscript used with non-Array variable.


    Ganz einfach: $coord ist kein Array! Deshalb olltest du vorher immer überprüfen, ob dem so ist. Dazu könntest du dir ja mal die Funktion IsArray() anschauen... ;)

    LG
    Christoph :)

    • Offizieller Beitrag

    aber ich weiss trotzdem nicht weiter


    "$coord ist kein Array! Deshalb olltest du vorher immer überprüfen, ob dem so ist. Dazu könntest du dir ja mal die Funktion IsArray() anschauen.."

    Wenn du damit nichts anfangen kannst, frag ich mich was du hier willst.
    Verdammt nochmal: [Blockierte Grafik: http://www.bug-fix.info/rtfm_gun.gif] [Blockierte Grafik: http://www.bug-fix.info/rtfm_book.gif]

  • es tut mir leid, dass ich keine Kentnisse habe und dass das für euch Kinderkram ist.

    Ich will auch gar nicht AutoIt beherrschen, (und bitte nicht falsch aufnehmen, das soll jetzt nicht ignorant klingen), aber ich brauche nur dieses Skript. Um es wirklich zu erlernen fehlt es mir an Zeit und leider auch an Geduld. Und damit sei auch mal die Frage, was ich hier will beantwortet.

  • In wie weit hilft mir denn diese Seite hier:

    http://translation.autoit.de/onlinehilfe/functions/IsArray.htm


    Für mich als Person ohne (Vor)Kentnisse ist das ziemlich umständlich.

    Ich habe das angegebene Beispiel mal benutzt. Und wenn ich n Texteditor offen habe zeit mir ein Fenster die Fensterhöhe vom Editor an. Ja .... Okay .. Aber in wiefern lässt sich das auf meine Situation übertragen? $pos (aus dem beispiel) ist also ein array. okay. warum ist $coord keins und wie mache ich es zu einem? ^^

  • Schau mal hier.

    Die Funktion gibt bei Erfolg ein Array mit den Koordinaten zurück. Bei Misserfolg wird lediglich @error gesetzt.
    Wenn die Farbe also nicht gefunden wird, ist $coord kein Array.

    Eine mögliche Lösung zu dem Problem wäre zum Beispiel so etwas:

    [autoit]

    Do
    $coord = PixelSearch(1242, 582, 1255, 591, $farbe)
    ; Sleep (10)
    Until IsArray ($coord) ; Dieser Block entspricht Zeile 4 deines Scripts

    [/autoit]

    Damit wird nach der Farbe so lange gesucht, bis $coord ein Array ist.

  • ahh ok, das klingt logisch.

    also auf mein Skript bezogen würde es so aussehen, oder?



    ich benutze die PixelSearch-Funktion ja 5 mal. Das "Do Until" verhält sich aber anders als die While-Schleife oder? Oder wird die erste Pixelsearch-Funktion solange ausgeführt bis die Farbe gefunden wurde und die anderen nicht weiter ausgeführt in der Zeit? Oder wird die Erste Pixelsearch-Funktion ausgeführt und falls er nichts findet geht er zur nächsten PixelSearch? So sollte es sein.