Pixelsearch - von unten nach oben?

  • Moin,

    ich wollte fragen, ob man mit pixelsearch von unten nach oben den Bildschirm nach der bestimmten Farbe
    absuchen kann. Normal sucht pixelsearch ja die Farve von oben nach unten. Kann man das irgendwie einfach umdrehen?

    Bei der Hilfe : http://translation.autoit.de/onlinehilfe/fu…PixelSearch.htm
    habe ich auch unter Bemerkungen gefunden, dass man die Suchrichtung "optimieren" kann.
    Aber da steht nicht wie.

    LG, Max

  • Wir haben auch kein anderes Pixelsearch als du. Mehr gibts nativ nicht. Wenndann über irgendwelche udf's oder direkt per ddl-calls
    Erklär doch endlich mal wofür du Pixelsearch brauchst!!!

  • Du kannst die Suchrichtung ändern indem du die entsprechenden Koordinaten deines Suchrechtecks vertauschst.. in der Hilfe wird unter Bemerkungen der Zusammenhang zwischen den Größen der Koordinaten und der Suchrichtung nochmal erklärt ;)

  • Wenn es um einfaches Pixelsuchen auf dem gesamtem Monitorinhalt geht, gibt es ca. doppelt bis 4x so schnelle Varianten im Vergleich zu Pixelsearch.
    Je kleiner die Suchfläche, bspw. ein Fenster, desto schneller die Suche.

    Btw. bei Win7 AERO ausschalten bringt ca. Faktor 3-4 beim Pixelsearch!

    Spoiler anzeigen
    [autoit]

    #include <WinAPI.au3>
    #include <StructureConstants.au3>
    #AutoIt3Wrapper_UseX64=n

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

    local $ptr,$hbmp
    $DC=_CreateNewBmp32(@DesktopWidth, @DesktopHeight, $ptr, $hbmp)

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

    $t=timerinit()
    $hDC = _WinAPI_GetDC(0)
    _WinAPI_BitBlt($DC,0,0,@DesktopWidth,@DesktopHeight,$hdc,0,0,0xCC0020) ;desktop nach bitmap blitten
    $col=0xFFBAD27C
    $ret=PixelSuchen32($ptr, $col, @DesktopHeight*@DesktopWidth,@DesktopWidth)
    msgbox(0,timerdiff($t),$ret[0] & @crlf & $ret[1])

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

    $col=0xBAD27C
    $t=timerinit()
    $ret=PixelSearch(0,0,@DesktopWidth,@DesktopHeight,$col)
    msgbox(0,timerdiff($t),$ret[0] & @crlf & $ret[1])

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

    Func PixelSuchen32($ptr, $col, $Breite_x_Hoehe,$Breite) ;pointer auf die Bitmap, Farbe und Größe der Bitmap
    $bytecode = "0x8B7C24048B4424088B54240C8B5C241089D1F2AFB80000000083F900741383C10129CA89D0BA00000000F7F3C1E21001D0C3"
    $tCodebuffer = DllStructCreate("byte[" & StringLen($bytecode) / 2 - 1 & "]") ;Speicher für den Bytecode reservieren
    DllStructSetData($tCodebuffer, 1, $bytecode) ;Bytecode in den Speicher schreiben
    $Ret = DllCalladdress( "dword:cdecl", DllStructGetPtr($tCodebuffer), "ptr", $ptr, "int", $col, "int", $Breite_x_Hoehe, "int", $Breite);bytecode aufrufen, rückgabe in a[0], Aufruf IMMER mit 4 Parametern!
    if $ret[0]=0 or @error then return 0 ;Pixel wurde nicht gefunden
    dim $koord[2]
    ;die oberen 16 Bit von EAX enthalten die x-Koordinate, die unteren 16 Bit enthalten die y-koordinate
    $koord[0]=BitShift($ret[0],16) ;x-Koordinate
    $koord[1]=Bitand($ret[0],0x0000FFFF);y-Koordinate
    return $koord
    EndFunc ;==>PixelSuchen32

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

    Func _CreateNewBmp32($iwidth, $iheight, ByRef $ptr, ByRef $hbmp) ;erstellt leere 32-bit-Bitmap; Rückgabe $HDC und $ptr und handle auf die Bitmapdaten
    Local $hcdc = _WinAPI_CreateCompatibleDC(0) ;Desktop-Kompatiblen DeviceContext erstellen lassen
    Local $tBMI = DllStructCreate($tagBITMAPINFO) ;Struktur der Bitmapinfo erstellen und Daten eintragen
    ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $tagBITMAPINFO = ' & $tagBITMAPINFO & @crlf & '>Error code: ' & @error & @crlf) ;### Debug Console
    DllStructSetData($tBMI, 1, DllStructGetSize($tBMI) - 4);Structgröße abzüglich der Daten für die Palette
    DllStructSetData($tBMI, 2, $iwidth)
    DllStructSetData($tBMI, 3, -$iheight) ;minus =standard = bottomup
    DllStructSetData($tBMI, 4, 1)
    DllStructSetData($tBMI, 5, 32) ;32 Bit = 4 Bytes => AABBGGRR
    Local $adib = DllCall('gdi32.dll', 'ptr', 'CreateDIBSection', 'hwnd', 0, 'ptr', DllStructGetPtr($tBMI), 'uint', 1, 'ptr*', 0, 'ptr', 0, 'uint', 0)
    $hbmp = $adib[0] ;hbitmap handle auf die Bitmap, auch per GDI+ zu verwenden
    $ptr = $adib[4] ;pointer auf den Anfang der Bitmapdaten, vom Assembler verwendet
    ;_arraydisplay($adib)
    _WinAPI_SelectObject($hcdc, $hbmp) ;objekt hbitmap in DC
    Return $hcdc ;DC der Bitmap zurückgeben
    EndFunc ;==>_CreateNewBmp32

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


    Der ASM-code ist übrigens HIER vorgestellt

    Wenn man den Code näher untersucht stellt man fest, dass 90% der Zeit für das "blitten" des Desktops in die Bitmap drauf geht, das eigentliche suchen des Pixels dauert nur ca. 2-3ms.

    //Edit durch Verwendung von SSE gelingt die Suche unter 1ms!
    "0x8B7C24048B4424088B54240C8B5C241089D1660F6ED8660F62DB660F62DB9090660F6F07660F76C30F50C083C71083E904741D83F80074E80FBCC029CA89D183E90401C189C831D2F7F3C1E21001D0C331C0C3"

    ciao
    Andy


    "Schlechtes Benehmen halten die Leute doch nur deswegen für eine Art Vorrecht, weil keiner ihnen aufs Maul haut." Klaus Kinski
    "Hint: Write comments after each line. So you can (better) see what your program does and what it not does. And we can see what you're thinking what your program does and we can point to the missunderstandings." A-Jay

    Wie man Fragen richtig stellt... Tutorial: Wie man Script-Fehler findet und beseitigt...X-Y-Problem

    2 Mal editiert, zuletzt von Andy (21. September 2014 um 17:17)

  • Um übrigens noch etwas zur Frage nach der "Rückwärtssuche" (v. unten n. oben) beizutragen: In der Funktion CreateNewBmp32() wird die BITMAPINFOHEADER-Struct mit der Höhe der Bitmap belegt. Standardmäßig werden Bitmaps "bottom up" (also von unten nach oben) dargestellt!

    [autoit]

    DllStructSetData($tBMI, 3, -$iheight) ;minus =standard = bottomup

    [/autoit]


    Um nun also die Bitmap von unten nach oben zu durchsuchen, muss man nur die Bitmap mit der positiven Höhe erstellen :D

    [autoit]

    DllStructSetData($tBMI, 3, $iheight) ;positiv = top down

    [/autoit]

    ciao
    Andy


    "Schlechtes Benehmen halten die Leute doch nur deswegen für eine Art Vorrecht, weil keiner ihnen aufs Maul haut." Klaus Kinski
    "Hint: Write comments after each line. So you can (better) see what your program does and what it not does. And we can see what you're thinking what your program does and we can point to the missunderstandings." A-Jay

    Wie man Fragen richtig stellt... Tutorial: Wie man Script-Fehler findet und beseitigt...X-Y-Problem

    Einmal editiert, zuletzt von Andy (22. September 2014 um 19:36)