Entwickler-Ecke

Windows API - Pixel auf Desktop [SCHNELL] auswerten!


SAiBOT - Fr 24.07.09 16:03
Titel: Pixel auf Desktop [SCHNELL] auswerten!
Hallo,
ich habe es bisher immer so gemacht:
-ein TBitmap erstellt
-mit GetDC das hDC des Desktops geholt
-mit CopyRect die benötigten Desktop Pixel ins TBitmap kopiert
-per TBitmap.ScanLine die gewünschten Pixel ausgewertet

Das ist schonmal schneller als TCanvas.GetPixel nur leider ist mir das noch viel zu langsam.
Gibt es eine schnellere Methode?
Villeicht nur mit Hilfe der API?


platzwart - Fr 24.07.09 19:46

Versuch mal die TBitmap32 aus den Graphics32, die ist viiiiiiiiiiel schneller ;)


jaenicke - Fr 24.07.09 20:27

Und noch besser:
Nimm direkt GetPixel [http://msdn.microsoft.com/en-us/library/dd144909.aspx] und wende das auf den DC an... ;-)


SAiBOT - Fr 24.07.09 20:53

user profile iconplatzwart hat folgendes geschrieben Zum zitierten Posting springen:
Versuch mal die TBitmap32 aus den Graphics32, die ist viiiiiiiiiiel schneller ;)


ja sieht schonmal besser aus, danke!

user profile iconjaenicke hat folgendes geschrieben Zum zitierten Posting springen:
Und noch besser:
Nimm direkt GetPixel [http://msdn.microsoft.com/en-us/library/dd144909.aspx] und wende das auf den DC an... ;-)


mag für einzelne Pixel gut sein, aber will man mehrere Prüfungen machen taugt diese Funktion nicht viel!


uall@ogc - Fr 24.07.09 21:33

Mittels ScanLine hast du ja schon dirket den zugriff auf die einzelen Pixel (über Pointer) da wirst du nicht viel machen können. Das langsame ist ja das BitBlt (CopyRect). Versuch es mal direkt mit der Api und setz vorher ganz wichtig das Pixelformat des Bitmaps auf die Desktop Farbtiefe (z.B. pf32Bit). Dann sollte das kopieren aus dem DC in den Buffer schnell sein. Dann ist halt die Frage wie dein Code zur Auswertung strukturiert ist. Ggf. Kannst du mit Assembler optimieren.

Andere Frage: Was hast du vor? (z.B. bei Spielen gehts eventl in Ogl über glReadPixels schneller etc.)


jaenicke - Fr 24.07.09 21:45

user profile iconSAiBOT hat folgendes geschrieben Zum zitierten Posting springen:
mag für einzelne Pixel gut sein, aber will man mehrere Prüfungen machen taugt diese Funktion nicht viel!
Das stimmt, ich hatte das jetzt so verstanden, dass vor allem immer wieder das Bild geholt wird. Wenn es um viele Pixel jeweils geht, dann ist das mit einzelnen Pixeln so natürlich nicht so sinnvoll, das stimmt.


SAiBOT - Sa 25.07.09 17:12

user profile iconuall@ogc hat folgendes geschrieben Zum zitierten Posting springen:
Mittels ScanLine hast du ja schon dirket den zugriff auf die einzelen Pixel (über Pointer) da wirst du nicht viel machen können. Das langsame ist ja das BitBlt (CopyRect). Versuch es mal direkt mit der Api und setz vorher ganz wichtig das Pixelformat des Bitmaps auf die Desktop Farbtiefe (z.B. pf32Bit). Dann sollte das kopieren aus dem DC in den Buffer schnell sein. Dann ist halt die Frage wie dein Code zur Auswertung strukturiert ist. Ggf. Kannst du mit Assembler optimieren.

Andere Frage: Was hast du vor? (z.B. bei Spielen gehts eventl in Ogl über glReadPixels schneller etc.)


Ich dachte daran das möglicherweise im DC/TCanvas-Objekt schon die ganzen Pixel in irgendeiner Form gespeichert sind und man über irgendwelche Offsets auf diese zugreifen kann! Irgendwo her muss sich CopyRect ja auch die Pixel holen.
Passende API-Funktionen scheint es nicht zu geben!

Die Auswertung/Assembler ist auch nicht so das Problem, wie du schon sagtest ist es CopyRect!

Es gibt leider keine anderen Vorgehensweisen für mein Problem.


uall@ogc - Sa 25.07.09 18:46

Copyrect wird nichts anderes als gdi32.BitBlt aufrufen (ungetestet). Das ruft dann die entsprechende Funktion im Kernel auf, die das dann kopiert.

ScanLine liefert dir die Adresse zurück auf die Zeile des Bildes im Speicher deines Programmes (welches mittels BitBlt kopiert wurde). Das ist halt nur ein "Screenshot".

Als alternative gibt es eben das hooken bzw. auslesen direkt aus dem Fremprozess. Wenn es sich z.b. um ein Bild handelt was du auslesen willst so wird das in irgeneiner Form dort im Zielprozess vorliegen. Das kannst du dann natürlich auch direkt mit ReadProcessMemory auslesen. Wenn das was du aber haben willst z.B. per gdi32.LineTo etc. ausgegeben wird musst du das hooken. Ist es z.B. ein OpenGL Programm kann man ggf die APIs hooken (glBegin / glVertex3f).

Du kannst jedenfalls nicht direkt auf die Bildschirmdaten aus deinem Programm aus zugreifen können, sondern musst diese a) in deinen Speicher kopieren (ReadProcessMemory aus dem Fremdprozesss, BitBlt als Screenshot über die WinAPI) oder dich aber in das Programm einklinken welches du überwachen willst und die verwendeten funktionen hooken (glBegin usw.)


Martok - Sa 25.07.09 18:52

user profile iconuall@ogc hat folgendes geschrieben Zum zitierten Posting springen:
Du kannst jedenfalls nicht direkt auf die Bildschirmdaten aus deinem Programm aus zugreifen können, sondern musst diese a) in deinen Speicher kopieren (ReadProcessMemory aus dem Fremdprozesss, BitBlt als Screenshot über die WinAPI)


Fällt mir grade mal ein: Doch, natürlich. Dafür gibts verschiedene Treiber-Tricks, vor allem sicher Mirror-Driver a la Mirage. Der wird auch von vielen VNCs genutzt...

VHScreenCap gibts auch noch, aber ob der sonderlich sinnoll ist wage ich noch zu bewzweifeln.


uall@ogc - Sa 25.07.09 18:57

Ja auf Treiber bin ich jetzt nicht eingegangen. Und CopyRect verwendet StretchBlt gerade nachgeschaut.


SAiBOT - Sa 01.08.09 18:30

user profile iconMartok hat folgendes geschrieben Zum zitierten Posting springen:
user profile iconuall@ogc hat folgendes geschrieben Zum zitierten Posting springen:
Du kannst jedenfalls nicht direkt auf die Bildschirmdaten aus deinem Programm aus zugreifen können, sondern musst diese a) in deinen Speicher kopieren (ReadProcessMemory aus dem Fremdprozesss, BitBlt als Screenshot über die WinAPI)


Fällt mir grade mal ein: Doch, natürlich. Dafür gibts verschiedene Treiber-Tricks, vor allem sicher Mirror-Driver a la Mirage. Der wird auch von vielen VNCs genutzt...

VHScreenCap gibts auch noch, aber ob der sonderlich sinnoll ist wage ich noch zu bewzweifeln.


Das sieht vielversprechend aus vielen Dank!