Canvas auslesen? (was nicht von BMax reingeschrieben wurde)
Übersicht

#ReaperNewsposterBetreff: Canvas auslesen? (was nicht von BMax reingeschrieben wurde) |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Also ich versuche nun schon länger den Desktop (von Windows) auszulesen. Mit BPlus geht das ja ganz einfach, und vorallem sehr schnell.
Für BMax habe ich nun auch schon einige sachen gefunden, mit denen man zwar auch ein Bild bekommt, welche aber doch extrem langsamm sind. Also einmal habe ich diese Funktion hier, welche ~60ms braucht: Code: [AUSKLAPPEN] Function GetDesktopPixmap:TPixmap()
Extern "Win32" Function GetDIBits(hdc:Int, bitmap:Int, Start:Int, Num:Int, bits:Byte Ptr, lpbi:Byte Ptr, usage:Int) Function CreateCompatibleBitmap(hdc:Int, Width:Int, Height:Int) Function CreateDIBSection(hdc:Int, pbmi:Byte Ptr, usage:Int, Bits:Byte Ptr, hSection:Int, Offset:Int) Function SelectObject(hdc:Int, obj:Int) Function CreateCompatibleDC(hdc:Int) Function GetDesktopWindow() Function GetWindowDC(hwnd:Int) Function GetDeviceCaps(hdc:Int, index:Int) Function DeleteDC(hdc:Int) Function DeleteObject(obj:Int) Function ReleaseDC(hwdn:Int, hdc:Int) Function BitBlt(hdc:Int,x:Int,y:Int,w:Int,h:Int,src_dc:Int,src_x:Int,src_y:Int,dwrop:Int) End Extern ?Win32 Type BITMAPINFO Field biSize:Int Field biWidth:Int Field biHeight:Int Field biPlanes:Short Field biBitCount:Short Field biCompression:Int Field biSizeImage:Int Field biXPelsPerMeter:Int Field biYPelsPerMeter:Int Field biClrUsed:Int Field biClrImportant:Int Field R:Byte Field G:Byte Field B:Byte Field Res:Byte End Type Const HORZRES:Int = 8 Const VERTRES:Int = 10 Local HwndDesktop:Int Local hdcDesktop:Int Local hdcMem:Int Local DesktopWidth:Int Local DesktopHeight:Int Local bmpMem:Int Local INFO:BITMAPINFO Local FinalPixmap:TPixmap HwndDesktop = GetDesktopWindow() If Not HwndDesktop Return Null EndIf hdcDesktop = GetWindowDC(HwndDesktop) If Not HdcDesktop Return Null EndIf hdcMem = CreateCompatibleDC(hdcDesktop) If Not HdcMem Return Null EndIf DesktopWidth = GetDeviceCaps(hdcDesktop, HORZRES) DesktopHeight = GetDeviceCaps(hdcDesktop, VERTRES) If DesktopWidth = 0 Or DesktopHeight = 0 Return Null EndIf bmpMem = CreateCompatibleBitmap(hdcDesktop, DesktopWidth, DesktopHeight) If Not BmpMem Return Null EndIf If Not SelectObject(HdcMem, bmpMem) Return Null EndIf Info = New BITMAPINFO Info.bisize = SizeOf(INFO) info.BiWidth = DesktopWidth Info.biHeight = DesktopHeight Info.biPlanes = 1 info.biBitCount = 32 Info.biCompression = 0 If Not BitBlt(hdcMem,0,0,Info.biWidth,Info.biHeight, hdcDesktop,0,0,ROP_SRCCOPY) Return Null EndIf FinalPixmap = CreatePixmap(info.biWidth, info.biHeight, PF_BGRA8888) If Not GetDIBits(hdcMem, bmpMem, 10, Info.biHeight, FinalPixmap.PixelPtr(0,0), info, 0) Return Null EndIf FinalPixmap = YFlipPixmap(FinalPixmap) DeleteDC(HdcMem) DeleteObject(bmpMem) ReleaseDC(hwndDesktop, hdcDesktop) Return FinalPixmap ? ?Linux Return Null ? ?MacOs Return Null ? End Function Das langsammste an dieser geschichte ist die Funktion GetDIBits(). Nun geht das ganze auch noch etwas kürzer (und auch schneller): Code: [AUSKLAPPEN] Window:TGadget = CreateWindow("Desktop", 250, 250, ClientWidth(Desktop()), ClientHeight(Desktop()))
canvas:TGadget = CreateCanvas(0,0,1024,768, Window) dsDC = GetDC(QueryGadget(canvas, QUERY_HWND_CLIENT)) dhWnd = GetDesktopWindow() BitBlt dsDC, 0, 0, ClientWidth(Desktop()), ClientHeight(Desktop()), GetDC(dhWnd), 0, 0, $00CC0020 Nun befindet sich bei dem Code sogar der Screenshot vom Desktop in dem Canvas, aber wenn ich versuche irgend etwas aus dem Canvas zu lesen, ist es leer. Ich vermute einfach mal, das es insofern auch an Max2D liegt. Weiß vielleicht jemand eine Funktion (von Windows oder so) mit der man direkt den Inhalt vom Canvas auslesen kann? Hab auch schonmal versucht das ganze in eine Bank zu hauen, geht aber leider auch nicht (bleibt leer) ![]() Oder weiß so noch jemand etwas? |
||
AMD Athlon 64 3500+, ATI AX800 Pro/TD, 2048 MB DRR 400 von Infineon, ♥RIP♥ (2005 - Juli 2015 -> sic!)
Blitz3D, BlitzMax, MaxGUI, Monkey X; Win7 |
Dreamora |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Aus einem Canvas zu lesen macht keinen Sinn.
Was da drin angezeigt wird ist der aktuelle Frontbuffer() Was du also auslesen musst ist dieser. Davon würd ich aber eigentlich abraten, da belässt du die Desktop Daten lieber in einem Pixmap und liest sie aus dem Pixmap aus mit den ReadPixel Befehlen oder durch die Abfrage des DatenPtr des Pixmaps und direkten Array Zugriffen auf diesen. (via Bank is zwar net nette Idee, jedoch ist ein Pixmap schon nichts anderes als ein Array mit Farbinformationen) Der Grund ist recht simpel: Ausm Frontbuffer auslesen heisst FrontBuffer lock, was nicht gerade die schnellste Operation ist und auch net wirklich sinnvoll ist zu nutzen, denn es gibt keine Anwendung dafür (alles geht auch via Backbuffer) Was willst du denn damit genau machen? |
||
Ihr findet die aktuellen Projekte unter Gayasoft und könnt mich unter @gayasoft auf Twitter erreichen. |
#ReaperNewsposter |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Also das Desktopimage will ich (zu mindestens teilweise) über das Netzwerk verschicken, deshalb ist es auch nicht so wichtig, als was mit die Daten vorliegen (also ob Pixmap oder Bank).
Und im erstem Code schreibt die Funktion GetDIBits() die Bilddaten in die Pixmap. Und ausgerechnet diese Funktion braucht rund 50ms dafür ![]() Ich hab noch keine andere Funktion für GetDIBits() gefunden :-/ Aber irgendetwas muss es ja geben, schließlich geht es mit BPlus ja mit weniger als 1ms ![]() |
||
AMD Athlon 64 3500+, ATI AX800 Pro/TD, 2048 MB DRR 400 von Infineon, ♥RIP♥ (2005 - Juli 2015 -> sic!)
Blitz3D, BlitzMax, MaxGUI, Monkey X; Win7 |
Dreamora |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Ich würd ma sagen da gibts 2 Möglichkeiten wie das geht:
1. Umleitung des Renderns in eine DirectSurface (nicht möglich in BM sofern du das nicht von Grund auf selbst implementierst) 2. Es gibt ne möglichkeit direkt an den Desktop Buffer ran zu kommen, also an den Byte Ptr davon und es auszulesen. |
||
Ihr findet die aktuellen Projekte unter Gayasoft und könnt mich unter @gayasoft auf Twitter erreichen. |
![]() |
d-bug |
![]() Antworten mit Zitat ![]() |
---|---|---|
Bei deiner Funktion da oben sind 2 kleinere Fehler drin:
1. Gehst du davon aus, dass jeder Desktop eine Farbtiefe von 32bit hat. Ändere mal: Code: [AUSKLAPPEN] info.biBitCount = 32
nach: Code: [AUSKLAPPEN] Const BITSPIXEL:Int = 12
info.biBitCount = GetDeviceCaps (hdcDesktop, BITSPIXEL) 2. Das Format was du bei der Pixmap zurück gibst sorgt schon mal für lustige Effekte. Bei Beschwerden solltest du die Pixmap nach PF_BGR888 konvertieren. und noch ein letztes... Durch importieren des Modules pub.win32 bekommst du den Type BITMAPINFOHEADER und 90% deiner API-Calls (außer ReleaseDC, glaube ich) und Konstanten gratis dazu. Aber ich denke mal, dass weißt du bereits. ![]() Hatte jetzt nichts mit dem Kern des Threads zu tun, aber ich dachte mir, ich weise dich mal darauf hin! |
||
#ReaperNewsposter |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
d-bug hat Folgendes geschrieben: und noch ein letztes... Durch importieren des Modules pub.win32 bekommst du den Type BITMAPINFOHEADER und 90% deiner API-Calls (außer ReleaseDC, glaube ich) und Konstanten gratis dazu. Aber ich denke mal, dass weißt du bereits. ![]() Danke für die Hinweise. Hatte den Code wo gefunden ![]() Und..mhh... Pub.Win32? Mhh..^^ Ok, ich gebs zu, wuste ich noch nicht ![]() Und ich frage mich aber immernoch, warum die nicht einfach alle RGB nehmen.... grml.. -.- naja.. Ich mag lustige Effekte ![]() @Dreamora: Also zu 1.: Ich würde mal sagen, dass das noch zu hoch für mich ist ![]() ![]() Zu 2: Ok, das könnte mir dann doch vielleicht weiter helfen ![]() Aber habe bislang den Befehl noch nicht gefunden. Also falls du ihn rein zufällig weist, fände ich das auch toll ![]() Ich schätze mal, dass der Befehl nämlich eh nichts mit Desktop und Buffer heißt, wodurch ich ihn bislang dann auch noch nicht gefunden habe, naja, ich such mal weiter ![]() ![]() PS: Meint ihr, es würde was bringen, wenn man Sibly fragen würde. Er müsste es ja wissen, angesichts BlitzPlus. Aber ob er da irgendetwas rausrückt..? |
||
AMD Athlon 64 3500+, ATI AX800 Pro/TD, 2048 MB DRR 400 von Infineon, ♥RIP♥ (2005 - Juli 2015 -> sic!)
Blitz3D, BlitzMax, MaxGUI, Monkey X; Win7 |
![]() |
Suco-XBetreff: ...... |
![]() Antworten mit Zitat ![]() |
---|---|---|
Zeig mir bitte mal, wie du in Bplus den Desktop in weniger als einer MS ausliest.
@D-Bug: Die Desktop Screen Funktion habe ich damals geschrieben. Da war noch vieles anders mit BlitzMax. Mfg |
||
Intel Core 2 Quad Q8300, 4× 2500 MHz, 4096 MB DDR2-Ram, GeForce 9600GT 512 MB |
#ReaperNewsposter |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
So z.B.:
Code: [AUSKLAPPEN] img = CreateImage(ClientWidth(Desktop()), ClientHeight(Desktop()))
ms = MilliSecs() CopyRect 0,0,ClientWidth(Desktop())-1, ClientHeight(Desktop())-1,0,0, DesktopBuffer(),ImageBuffer(img) ms = MilliSecs()-ms Graphics 800, 600, 32, 2 Color 255,0,0 DebugLog "MilliSecs: " + ms While Not KeyHit(1) DrawImage img, 0,0 Text 10, 10, "MilliSecs: " + ms Flip 0 Cls Delay 10 Wend End Braucht bei mir sogar 0 ms ![]() |
||
AMD Athlon 64 3500+, ATI AX800 Pro/TD, 2048 MB DRR 400 von Infineon, ♥RIP♥ (2005 - Juli 2015 -> sic!)
Blitz3D, BlitzMax, MaxGUI, Monkey X; Win7 |
![]() |
d-bug |
![]() Antworten mit Zitat ![]() |
---|---|---|
@Suco-X
Ich weiß, dass es deine ist, hab sie schließlich für DesktopExtension auch übernommen. Hab sie allerdings dann ein wenig modifiziert. Ist zwar auch nicht schneller, aber die Punkte die ich #Reaper aufzeigte sind eliminiert. |
||
Dreamora |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Dein BB Code erinnert mich an was: Kick das Blit ma und versuchs mit MemCopy und kopiere es in den Pixmapbuffer (der gleich gross sein muss wie der Desktop und die gleiche Farbtiefe!)
denn evtl ist es auch der Blit der derart absäuft. |
||
Ihr findet die aktuellen Projekte unter Gayasoft und könnt mich unter @gayasoft auf Twitter erreichen. |
#ReaperNewsposter |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Blit? Den gibt es doch garnicht? :-/ ![]() Also ich hab nochmals nachgemessen, es ist GetDIBits() welcher geschlagene ~50ms braucht. Leider weiß ich nicht, wie ich MemCopy() richtig verwenden soll ![]() ![]() |
||
AMD Athlon 64 3500+, ATI AX800 Pro/TD, 2048 MB DRR 400 von Infineon, ♥RIP♥ (2005 - Juli 2015 -> sic!)
Blitz3D, BlitzMax, MaxGUI, Monkey X; Win7 |
Dreamora |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Gibts nicht?
BitBlt ist also eine Einbildung? ![]() Und MemCopy ist recht einfach zu verwenden, Es kopiert eine gewisse Anzahl Bytes vom Source ab Position Offset zum Zielbuffer an Position 0 Er vermute, schneller sein als der BitBlt wenn ich mich nicht irre. Denn WinAPI Grafik Befehle sind nicht auf Geschwindigkeit ausgelegt. |
||
Ihr findet die aktuellen Projekte unter Gayasoft und könnt mich unter @gayasoft auf Twitter erreichen. |
#ReaperNewsposter |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Mhh.. ![]() Meinst du das vielleicht so..? Code: [AUSKLAPPEN] MemCopy(FinalPixmap.PixelPtr(0,0), hdcDesktop, Info.biHeight*Info.biWidth*4)
Also richtig testen kann ich das noch nichtmal, da ich nicht weiß, wie ich aus dem Integer von hdcDesktop ein Byte Ptr machen soll :-/ |
||
AMD Athlon 64 3500+, ATI AX800 Pro/TD, 2048 MB DRR 400 von Infineon, ♥RIP♥ (2005 - Juli 2015 -> sic!)
Blitz3D, BlitzMax, MaxGUI, Monkey X; Win7 |
![]() |
Suco-XBetreff: .... |
![]() Antworten mit Zitat ![]() |
---|---|---|
Hups, habe nicht mehr an den Thread gedacht.
@Reaper: Was du da im BPlus Code gemacht hast, war eine einfache Kopieraktion von einem zum anderen Buffer. Wenn du die Pixel ausliest (Und das musst du ja, wenn du es übers Netzwerk verschicken willst), erweist sich die Bplus Lösung auch nicht als schnell. Mfg |
||
Intel Core 2 Quad Q8300, 4× 2500 MHz, 4096 MB DDR2-Ram, GeForce 9600GT 512 MB |
#ReaperNewsposter |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Naja, doch, sie ist schon schneller, bei dem bisherigem BMax Code sind es ja ~60ms + Pixelauslesezeit fürs Netzwerk. Aber ein doch sehr großes Problem am BMax Code ist, das es seltsamer weiße den PC ein wenig zum "laggen" bringt, zu mindestens was die Grafik angeht.
Mhh.. kann mir einer vielleicht auch einen Tipp geben, wie ich auf den DesktopBuffer zugreifen kann? In BMax gibt es ja insofern keine Buffer mehr ![]() |
||
AMD Athlon 64 3500+, ATI AX800 Pro/TD, 2048 MB DRR 400 von Infineon, ♥RIP♥ (2005 - Juli 2015 -> sic!)
Blitz3D, BlitzMax, MaxGUI, Monkey X; Win7 |
Dreamora |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Ich denke die MSDN wird da gewiss eine Lösung dafür haben, wird bloss seine Zeit brauchen bis du sie dort vermutlich finden wirst.
Eine andere Lösung: nein, vermutlich nicht. |
||
Ihr findet die aktuellen Projekte unter Gayasoft und könnt mich unter @gayasoft auf Twitter erreichen. |
![]() |
Suco-XBetreff: .... |
![]() Antworten mit Zitat ![]() |
---|---|---|
Bin schon etwas raus aus BB, aber wenn ich hier keinen Fehler eingebaut habe, bist du in BMX mit 60 ms noch sehr gut bedient.
Code: [AUSKLAPPEN] img = CreateImage(ClientWidth(Desktop()), ClientHeight(Desktop())) ms = MilliSecs() CopyRect 0,0,ClientWidth(Desktop())-1, ClientHeight(Desktop())-1,0,0, DesktopBuffer(),ImageBuffer(img) LockBuffer(ImageBuffer(img)) For x = 0 To ImageWidth(img)-1 For y = 0 To ImageHeight(img)-1 ReadPixelFast(x,y, ImageBuffer(img)) Next Next UnlockBuffer(ImageBuffer(img)) ms = MilliSecs()-ms Notify("Zeit: "+ms) kriege hier 780 ms, alleine fürs auslesen der Pixel. Die GetDesktopPixmap Funktion greift übrigens schon auf den Desktopbuffer zu. Die MSDN kannst du 10 Jahre durchsuchen, am besten gehst du mal in ein Deutsches WinAPI Forum und fragst da nach einer alternative. Gewisse Programme können ja schließlich sehr flott Videos vom Desktop aufnehmen, also muss es noch was anderes geben. Mfg |
||
Intel Core 2 Quad Q8300, 4× 2500 MHz, 4096 MB DDR2-Ram, GeForce 9600GT 512 MB |
#ReaperNewsposter |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Mhh... ok, Danke, daran habe ich nun auch nicht mehr gedacht. Das PixelMap auslesen ist in BMax vermutlich schneller als in B+? (Bei mir braucht es sogar rund 1000ms ^^° ![]() Dann werde ich mal irgendwelche anderen Foren dazu quälen ![]() ![]() MfG #Reaper |
||
AMD Athlon 64 3500+, ATI AX800 Pro/TD, 2048 MB DRR 400 von Infineon, ♥RIP♥ (2005 - Juli 2015 -> sic!)
Blitz3D, BlitzMax, MaxGUI, Monkey X; Win7 |
![]() |
Suco-XBetreff: .... |
![]() Antworten mit Zitat ![]() |
---|---|---|
Habe mich nochmal dran gehängt und mir ist was aufgefallen. Du versendest die Daten ja sowieso per Netzwerk, also kannst du dir den Schritt mit der Pixmap sparen.
Erst die Desktop Daten auslesen, in eine Pixmap hauen und danach aus der Pixmap auslesen, sind zwei Schritte zu viel. Du kannst das z.b so machen: Code: [AUSKLAPPEN] Local mem:Byte Ptr = MemAlloc((DesktopWidth*DesktopHeight)*3) If Not GetDIBits(hdcMem, bmpMem, 0, Info.biHeight, Mem, info, 0) Return Null EndIf Du rerservierst also einfach den nötigen Speicher und lässt ihn von der GetDIBits Funktion mit den Farbdaten des Desktops füllen. Diesen Speicherblock Mem lässt du dir von der Funktion statt der Pixmap zurückgeben. Danach gehst du den Speicherblock wie ein Array durch und schickst die Daten ab. Drüben angekommen, benutzt den CreateStaticPixmap Befehl, um die Daten wieder in eine brauchbare Pixmap zu wandeln. Ohne verschickung übers Netzwerk geht das hier in 30ms, also noch eine brauchbare Zeit. Wenn du mit der Pixmap arbeitest und die zum senden ausliest, dauert es hier z.b. 280 ms. Solltest du trotzdem noch eine alternative in irgendeinem Forum entdeckt haben, sag hier bitte bescheid. Mfg |
||
Intel Core 2 Quad Q8300, 4× 2500 MHz, 4096 MB DDR2-Ram, GeForce 9600GT 512 MB |
#ReaperNewsposter |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Oh, danke ![]() Aber es ist bei mir leider nur rund ~10 ms schneller als vorher (nach deinen Zeiten wäre es etwa doppelt so schnell). Aber ich glaube, dass ich wohl irgendetwas falsch gemacht habe. Denn seltsamer weise ist Mem immer Leer :-/ Hast du deinen Code vielleicht noch? Wundert mich nun auch, dass aufeinmal GetDIBits() so langsam ist, vorher war es ja immernoch BitBlt() :-/ Aber danke nochmals/schonmals ![]() |
||
AMD Athlon 64 3500+, ATI AX800 Pro/TD, 2048 MB DRR 400 von Infineon, ♥RIP♥ (2005 - Juli 2015 -> sic!)
Blitz3D, BlitzMax, MaxGUI, Monkey X; Win7 |
Übersicht


Powered by phpBB © 2001 - 2006, phpBB Group