# Spiel-Bilddaten auswerten



## dakimo (29. Nov 2012)

Hallo zusammen,

ich habe ein Frage und hoffe hier Anregungen zur Umsetzung zu bekommen.

Use Case:
In einem beliebigem Fenster läuft ein Programm mit bewegten Bildern (zb. ein Spiel).
Ich möchte diese Bilddaten auslesen und bei einem Ereignis im Bild mit der Maus mehrere Aktionen ausführen. 


Da ich aus dem jee Umfeld komme und bisher nicht mit Mulitimedia-Anwendungen gearbeitet habe fehlt mir der Ansatz wie ich starten soll. Ist es überhaupt halbwegs effizient machbar? 

Ich wäre für Tipps und Empfehlungen dankbar!

Viele Grüße
Dakimo


----------



## dayaftereh (29. Nov 2012)

Schau dir mal die Klasse Robot (Java 2 Platform SE v1.4.2) an, mit der kannst du ein Screenshot machen und die Mausbewegen bzw. eine Click Simulieren.


----------



## dakimo (11. Dez 2012)

Ja sehr interessant. Gibt es auch freie Bibliotheken mit denen ich ein Bild im Bild suchen kann? 
Als erstes proof of concept würde ich gerne Moorhühner schießen lassen. 

Viele Grüße
Dakimo


----------



## dayaftereh (11. Dez 2012)

Ich glaube ImageJ kann das, aber ich würde mal versuchen einen eignen Algorithmus zu Implementieren, denke mal das ist eine gute Übungsaufgabe.

Als ich gegoogle habe, fand ich viele anfangs Ideen für das finden von einem Image in einem anderen Image.


----------



## Helgon (12. Dez 2012)

Soll das ne Art Aimbot werden? Dann ist das der falsche Ansatz


----------



## trääät (12. Dez 2012)

@TO
wie helgon sagte : wenn das in Richtung aim-bot gehen soll ist das auf jeden fall die falsche Idee Java dafür nutzen zu wollen ...
proof of concept mag das gehen ... aber Performance solltest du nicht erwarten ...

ich hab etwas ähnliches mal zum knacken von captchas gebastelt ... naja ... also das mit dem "bild im bild suchen" kann man auch selbst recht performant schreiben ... dafür brauchts keine lib ... aber wirklich "live" wirst du das alleine auf grund der Geschwindigkeit von Java nicht hinbekommen ... da es schon alleine ungmöglich ist mit Robot ein halbwegs "flüssiges" desktop-tool zu bauen wo ein paar Frames die sekunde reichen laufen die meisten spiele mit 60 fps und aufwärts ... da würdest du nicht mal hinterher kommen wenn du nur jedes 2te oder 3te Frame prüfst ...


----------



## Firephoenix (12. Dez 2012)

Zumindest bei dem fps-Argument würde ich widersprechen.
Auch wenn das Spiel 60 fps rendert, so enthalten die Bilder doch fast identische Informationen.
Solange man keinen high-End fps-Aimbot schreibt müsste man also auch mit solchen Bildraten brauchbare Ergebnisse erzielen können.
Gruß


----------



## Dow Jones (12. Dez 2012)

dakimo hat gesagt.:


> Ich wäre für Tipps und Empfehlungen dankbar!



Hallo Dakimo,
das wäre eigentlich mal eine gute Gelegenheit sich in C einzuarbeiten. Schwer ist das auch nicht, und von der Performance her wird eine Lösung in C wahrscheinlich nicht schlechter sein als ein Javaprogramm (um es mal vorsichtig zu formulieren).

Ich rate einfach mal das du Windows verwendest. Da könnte dein Programm dann ziemlich simpel ausfallen:

```
// windows nach handler fuer das Fenster fragen
    myWindowHandler = FindWindow (NULL, "Name des Programms");  // z.B. "Calculator" fuer den Windows-Taschenrechner
    
    // ein paar Spielereien...
    ShowWindow(myWindowHandler, SW_RESTORE);   // Fenster hervorholen, falls es minimiert war
    SetForegroundWindow(myWindowHandler);   // Fenster in den Vordergrund holen
    SetFocus(myWindowHandler);    // Focus auf dieses Fenster setzen

    // einen Pixel aus dem Fenster auslesen
    HDC myDisplayCanvas = GetDC(myWindowHandler);
    COLORREF myPixelColor = GetPixel(myDisplayCanvas, x, y);

    // Tastendruck F1 simulieren
    keybd_event ((CHAR)(SHORT)VK_F1, 0,0,0 );
    keybd_event ((CHAR)(SHORT)VK_F1, 0, KEYEVENTF_KEYUP, 0 );

    // Mausklick simulieren
    mouse_event(MOUSEEVENTF_LEFTDOWN, 0,0,0,0);
    mouse_event(MOUSEEVENTF_LEFTUP, 0,0,0,0);
```

Fuer die Bewegung der Maus muss man berücksichtigen, das der Mauszeiger nicht in Pixeln sondern in Mickeys (ja, die Einheit heisst wirklich so) bewegt wird. Ein Bildschirm ist für die Maus immer 65.536 x 65.536 Mickeys groß, ganz egal welche Auflösung man für den Monitor gerade eingestellt hat. Um den Mauszeiger nun an die gewünschte Stelle auf dem Bildschirm zu bewegen muss man die Position (in Pixeln) erstmal in die Position (in Mickeys) umrechnen und kann dann einen entsprechenden Mausevent auslösen. Wenn der Mauszeiger beispielsweise an die Position 200/100 (relativ zur linken oberen Ecke des Fensters) bewegt werden soll dann könnte man das so schreiben:


```
RECT rectangle;
    GetWindowRect (myWindowHandler, &rectangle);
    int x = rectangle.left + 200;
    int y = rectangle.top + 100
    float mickeyPerPixelX = 65535.0 / (float)GetSystemMetrics(SM_CXSCREEN);
    float mickeyPerPixelY = 65535.0 / (float)GetSystemMetrics(SM_CYSCREEN);
    mouse_eventw(MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE,
        (int)(x * mickeyPerPixelX), (int)(y * mickeyPerPixelY), 0, 0);
```

Beim Kompilieren musst du die Lib gdi32 einbinden, die API dazu lässt sich problemlos ergoogeln.


----------

