Hallo,
ich benötige dringend Rat. Meine Anwendung ist dafür gedacht, einen Screenshot anzufertigen, sobald bei einer Drittanwendung (ein Spiel) ein bestimmtes Muster auftaucht (es handelt sich um eine Punktetabelle) - sprich sobald diese Tabelle erscheint, soll meine Anwendung einen Screenshot speichern. Dafür benutze ich die getPixel function.
Hier der relevante Teil meiner Anwendung:
Zunächst einmal überprüfe ich via GetForegroundWindow und FindWindow, ob die hwnd PID der Drittanwendung mit derjenigen PID übereinstimmt, in der sich der Benutzer momentan befindet (fokus). Das ist erforderlich, damit nicht von anderen Anwendungen Screenshots erstellt werden können, die eine ähnliche Anordnung von Pixeln haben (z.B. wenn man sich im Browser befindet usw.). Wenn die gewünschte Anwendung im Vordergrund ist, speichere ich in lColor bis lColor5 Farbwerte von den relevanten Koordinaten, und überprüfe, ob diese sich in einem bestimmten Farbspektrum befinden. Um es zu vereinfachen als Beispiel: Sobald Pixel 563, 759 Rot und sobald Pixel 599, 800 Blau sind, soll ein Screenshot angefertigt werden. Die GetPixel Funktion liefert einen Wert, der erst durch Hexadezimalumwandlung RGB ergibt, was ich mir aber erspare. Dadurch bedeuted z.B. 16.777.215 = weiß.
Diese Abfrage schließt alle Szenarien aus, in denen die Drittanwendung nicht die Punktetabelle zeigt. Somit habe ich meine gewünschte Methode, die jede Punktetabelle als Screenshot abspeichert.
Nun zu meinem Problem: Es handelt sich um ein Spiel (genauer gesagt um einen FPS). Wenn ich meine Sub PixelCheck() in einer While-Schleife ca. jede Millisekunde ausführe, stellt sich das als extrem unperformant heraus und es ruckelt im Spiel, weil meine Anwendung in Echtzeit immer wieder diese 5 Pixel abfragt. Selbst wenn ich meine Sub in einen Timer packe, der nur jede Sekunde abfragt, ruckelt es in jeder Sekunde. GetPixel ist demnach für mich unbrauchbar nehme ich an.
Lohnt es sich alternativ 5 * 1x1 Bitmaps von diesen Positionen anzulegen und diese auf ihre Farbwerte zu überprüfen? Ist das "schneller"? Gibt es weitere Möglichkeiten oder Ideen, wie sich das optimieren lässt? Das einzige was ich bereits probiert habe, ist meine Sub in einen anderen Thread auszulagern, was allerdings wenig gebracht habe. Ich weiß auch leider nicht, wie GetPixel im Detail arbeitet. Ich erstelle jedes Mal einen device context über GetDC, wobei GetDC(0) den gesamten Bildschirm erfasst, liegt hierin vielleicht das Problem? Irgendwelche Vorschläge, um mein Vorhaben zu realisieren?
Mit freundlichen Grüßen
ich benötige dringend Rat. Meine Anwendung ist dafür gedacht, einen Screenshot anzufertigen, sobald bei einer Drittanwendung (ein Spiel) ein bestimmtes Muster auftaucht (es handelt sich um eine Punktetabelle) - sprich sobald diese Tabelle erscheint, soll meine Anwendung einen Screenshot speichern. Dafür benutze ich die getPixel function.
Hier der relevante Teil meiner Anwendung:
VB.NET-Quellcode
- Public Class Form1
- Private Declare Function GetForegroundWindow Lib "user32.dll" () As IntPtr
- Private Declare Auto Function FindWindow Lib "user32.dll" (ByVal lpClassName As String, ByVal lpWindowName As String) As IntPtr
- Private Declare Function GetPixel Lib "gdi32" (ByVal hdc As Integer, ByVal x As Integer, ByVal y As Integer) As Integer
- Private Declare Function GetDC Lib "user32" Alias "GetDC" (ByVal hwnd As Integer) As Integer
- Dim intFenster_Vordergrund As IntPtr
- Dim windowTitle As String = "warrock"
- Public Sub PixelCheck()
- Dim hWnd = FindWindowByTitle(windowTitle)
- intFenster_Vordergrund = CType(GetForegroundWindow().ToString, IntPtr)
- If hWnd = intFenster_Vordergrund Then
- Dim lColor As Integer = GetPixel(GetDC(0), 563, 759)
- Dim lColor2 As Integer = GetPixel(GetDC(0), 599, 800)
- Dim lColor3 As Integer = GetPixel(GetDC(0), 1160, 831)
- Dim lColor4 As Integer = GetPixel(GetDC(0), 608, 827)
- Dim lColor5 As Integer = GetPixel(GetDC(0), 887, 760)
- If Not ((lColor <= 6000000) Or (lColor >= 10000000)) And Not ((lColor2 <= 12000000) Or (lColor2 >= 15000000)) And Not ((lColor3 <= 6000000) Or (lColor3 >= 9000000)) And Not ((lColor4 <= 500000) Or (lColor4 >= 2000000)) And Not ((lColor5 <= 9000000) Or (lColor5 >= 12000000)) Then
- EndscoreCapture() 'fertigt den Screenshot an.
- End If
- End If
- End Sub
- End Class
Zunächst einmal überprüfe ich via GetForegroundWindow und FindWindow, ob die hwnd PID der Drittanwendung mit derjenigen PID übereinstimmt, in der sich der Benutzer momentan befindet (fokus). Das ist erforderlich, damit nicht von anderen Anwendungen Screenshots erstellt werden können, die eine ähnliche Anordnung von Pixeln haben (z.B. wenn man sich im Browser befindet usw.). Wenn die gewünschte Anwendung im Vordergrund ist, speichere ich in lColor bis lColor5 Farbwerte von den relevanten Koordinaten, und überprüfe, ob diese sich in einem bestimmten Farbspektrum befinden. Um es zu vereinfachen als Beispiel: Sobald Pixel 563, 759 Rot und sobald Pixel 599, 800 Blau sind, soll ein Screenshot angefertigt werden. Die GetPixel Funktion liefert einen Wert, der erst durch Hexadezimalumwandlung RGB ergibt, was ich mir aber erspare. Dadurch bedeuted z.B. 16.777.215 = weiß.
VB.NET-Quellcode
- If Not ((lColor <= 6000000) Or (lColor >= 10000000)) And Not ((lColor2 <= 12000000) Or (lColor2 >= 15000000)) And Not ((lColor3 <= 6000000) Or (lColor3 >= 9000000)) And Not ((lColor4 <= 500000) Or (lColor4 >= 2000000)) And Not ((lColor5 <= 9000000) Or (lColor5 >= 12000000)) Then
- EndscoreCapture()
- End If
Diese Abfrage schließt alle Szenarien aus, in denen die Drittanwendung nicht die Punktetabelle zeigt. Somit habe ich meine gewünschte Methode, die jede Punktetabelle als Screenshot abspeichert.
Nun zu meinem Problem: Es handelt sich um ein Spiel (genauer gesagt um einen FPS). Wenn ich meine Sub PixelCheck() in einer While-Schleife ca. jede Millisekunde ausführe, stellt sich das als extrem unperformant heraus und es ruckelt im Spiel, weil meine Anwendung in Echtzeit immer wieder diese 5 Pixel abfragt. Selbst wenn ich meine Sub in einen Timer packe, der nur jede Sekunde abfragt, ruckelt es in jeder Sekunde. GetPixel ist demnach für mich unbrauchbar nehme ich an.
Lohnt es sich alternativ 5 * 1x1 Bitmaps von diesen Positionen anzulegen und diese auf ihre Farbwerte zu überprüfen? Ist das "schneller"? Gibt es weitere Möglichkeiten oder Ideen, wie sich das optimieren lässt? Das einzige was ich bereits probiert habe, ist meine Sub in einen anderen Thread auszulagern, was allerdings wenig gebracht habe. Ich weiß auch leider nicht, wie GetPixel im Detail arbeitet. Ich erstelle jedes Mal einen device context über GetDC, wobei GetDC(0) den gesamten Bildschirm erfasst, liegt hierin vielleicht das Problem? Irgendwelche Vorschläge, um mein Vorhaben zu realisieren?
Mit freundlichen Grüßen
Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von „getaim“ ()