PixelGetColor vom gesamten Bildschirm

  • Ja wie im Titel beschrieben will ich jedes einzelne Pixel von meinem Bildschirm auslesen.(1024*76 8)

    Da es ja schwachsinnig wäre 1024*768 mal eine Variable mit PixelGetColor zu definieren wollte ich fragen was für andere Möglichkeiten es noch gibt.

    Spontan fällt mir Array ein aber das habe ich immer schon gehasst ^^

    Wenn ich dann alle Pixel habe würde ich gerne diese wieder auf den Bildschirm "malen".

    [Funktion ausm Autoit Forum]

    Spoiler anzeigen
    [autoit]

    Func SetPixel ($handle, $x, $y, $color)
    $dc= DllCall ("user32.dll", "int", "GetDC", "hwnd", $handle)
    DllCall ("gdi32.dll", "long", "SetPixel", "long", $dc[0], "long", $x, "long", $y, "long", $color)
    DllCall ("user32.dll", "int", "ReleaseDC", "hwnd", 0, "int", $dc[0])
    EndFunc

    [/autoit]

    //edit das Problem ist eigentlich nur diese Pixel auszulesen

    • Offizieller Beitrag

    Hi,

    Spoiler anzeigen
    [autoit]

    $re = _getDesktopPixelColors()
    _ArrayDisplay($re)

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

    Func _getDesktopPixelColors()
    Local $coord[@DesktopWidth][@DesktopHeight]
    For $x = 0 To UBound($coord, 1) - 1
    For $y = 0 To UBound($coord, 2) - 1
    $coord[$x][$y] = PixelGetColor($x, $y)
    Next
    Next
    Return $coord
    EndFunc ;==>_getDesktopPixelColors

    [/autoit]

    Mega

  • Ich habe das auch mal probiert, aber bei 300x300 braucht er schon 1 Sekunde zum einlesen und 8 zum zeichnen.

    Das Handel habe ich per Hand eingetragen, habe mir das mal in ein Notepad malen lassen, aber nicht grade farbecht oder :)

    Bild
    Testcode
    [autoit]


    #include <array.au3>
    #include <Date.au3>
    #Include <WinAPI.au3>

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

    $dheight = 300 ; @DesktopHeight
    $dwidth = 300 ; @DesktopWidth

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

    $arrcount = $dheight * $dwidth

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

    Dim $arr[$arrcount]
    $pos = 0
    $StartTicks = _TimeToTicks(@HOUR,@MIN,@SEC)

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

    For $x = 1 to $dheight
    For $y = 1 To $dwidth
    $arr[$pos] = PixelGetColor($x,$y)
    $pos += 1
    Next
    Next

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

    $pos = 0

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

    ;!!!!! Handel manuell eingetragen!!!!!!!
    $hWnd = "0x0044063A"

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

    ;_ArrayReverse($arr)
    For $x = 1 to $dheight
    For $y = 1 To $dwidth
    SetPixel($hWnd,$x,$y,$arr[$pos])
    $pos += 1
    Next
    Next
    $EndTicks = (_TimeToTicks(@HOUR,@MIN,@SEC) - $StartTicks) / 1000
    MsgBox(262144,'' , 'Dauer:' & $EndTicks & " Sekunden")

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

    Func SetPixel ($handle, $x, $y, $color)
    $dc= DllCall ("user32.dll", "int", "GetDC", "hwnd", $handle)
    DllCall ("gdi32.dll", "long", "SetPixel", "long", $dc[0], "long", $x, "long", $y, "long", $color)
    DllCall ("user32.dll", "int", "ReleaseDC", "hwnd", 0, "int", $dc[0])
    EndFunc

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

    Mfg
    Jens (McPoldy)

    Twitter: jkroeger

    Denn die Dinge, die wir erst lernen müssen, bevor wir sie tun, lernen wir beim Tun.(Aristoteles)

  • Weil Autoit standardmäßtig im
    RGB odus arbeitet,
    SetPixel aber mit BGR

    Also muss man entweder AUTOIT umstellen:
    OPt("ColorMode",1)
    oder diese Funktion zwischenschalten:

    [autoit]

    ;===============================================================================
    ;
    ; Function Name: _RGB_To_BGR
    ; Description:: Changes a RGB color value to BGR
    ; Parameter(s): RGB Color
    ; Requirement(s): ?
    ; Return Value(s): BGR color value
    ; Author(s): Prog@ndy
    ;
    ;===============================================================================
    ;
    Func _RGB_To_BGR($nColor)
    $r = BitAND( BitShift($nColor, 16), 0xff)
    $g = BitAND( BitShift($nColor, 8), 0xff)
    $b = BitAND($nColor, 0xff)
    Return BitShift($b, -16) + BitShift($g, -8) + $r
    EndFunc

    [/autoit]
    • Offizieller Beitrag

    Hi,

    es geht auch einfacher arbeite gerade an einer etwas variableren Lösung: (noch nicht fertig!)

    [autoit]

    #include<Array.au3>

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

    Run('notepad')
    Sleep(1000)
    Global $handle = WinGetHandle('Unbenannt - Editor')
    WinMove($handle, '', 300, 300, 500, 500, 1)

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

    Global $colors_A = _getPixelColors(0, 0, 300, 300)
    _paintPixel($colors_A, $handle, 0, 0)

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

    Func _getPixelColors($start_X = 0, $start_Y = 0, $end_X = @DesktopWidth, $end_Y = @DesktopHeight)
    Local $opt = Opt('ColorMode', 1)
    Local $coord[$end_X - $start_X][$end_Y - $start_Y]
    For $x = $start_X To UBound($coord, 1) - 1
    For $y = $start_Y To UBound($coord, 2) - 1
    $coord[$x][$y] = PixelGetColor($x, $y)
    Next
    Next
    Opt('ColorMode', $opt)
    Return $coord
    EndFunc ;==>_getPixelColors

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

    Func _paintPixel(ByRef $coord, $handle, $start_X = 0, $start_Y = 0)
    For $x = 0 To UBound($coord, 1) - 1
    For $y = 0 To UBound($coord, 2) - 1
    SetPixel($handle, $x + $start_X, $y + $start_Y, $coord[$x][$y])
    Next
    Next
    Return $coord
    EndFunc ;==>_paintPixel

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

    Func SetPixel($handle, $x, $y, $color)
    $dc = DllCall("user32.dll", "int", "GetDC", "hwnd", $handle)
    DllCall("gdi32.dll", "long", "SetPixel", "long", $dc[0], "long", $x, "long", $y, "long", $color)
    DllCall("user32.dll", "int", "ReleaseDC", "hwnd", 0, "int", $dc[0])
    EndFunc ;==>SetPixel

    [/autoit]

    Mega

    • Offizieller Beitrag

    HI,

    so fertig:

    [autoit]

    #include<Array.au3>

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

    Run('notepad')
    Sleep(1000)
    Global $handle = WinGetHandle('Unbenannt - Editor')
    WinMove($handle, '', 300, 300, 500, 500, 1)

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

    Global $colors_A = _getPixelColors(50, 50, 200, 200)
    _paintPixel($colors_A, $handle, 50, 50)

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

    Func _getPixelColors($start_X = 0, $start_Y = 0, $end_X = @DesktopWidth, $end_Y = @DesktopHeight)
    Local $opt = Opt('ColorMode', 1)
    Local $coord[$end_X - $start_X][$end_Y - $start_Y]
    For $x = 0 To UBound($coord, 1) - 1
    For $y = 0 To UBound($coord, 2) - 1
    $coord[$x][$y] = PixelGetColor($x + $start_X, $y + $start_Y)
    Next
    Next
    Opt('ColorMode', $opt)
    Return $coord
    EndFunc ;==>_getPixelColors

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

    Func _paintPixel(ByRef $coord, $handle, $start_X = 0, $start_Y = 0)
    For $x = 0 To UBound($coord, 1) - 1
    For $y = 0 To UBound($coord, 2) - 1
    SetPixel($handle, $x + $start_X, $y + $start_Y, $coord[$x][$y])
    Next
    Next
    Return $coord
    EndFunc ;==>_paintPixel

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

    Func SetPixel($handle, $x, $y, $color)
    Local $dc = DllCall("user32.dll", "int", "GetDC", "hwnd", $handle)
    DllCall("gdi32.dll", "long", "SetPixel", "long", $dc[0], "long", $x, "long", $y, "long", $color)
    DllCall("user32.dll", "int", "ReleaseDC", "hwnd", 0, "int", $dc[0])
    EndFunc ;==>SetPixel

    [/autoit]

    Mega

  • Wobei man mit Screenshot oder BitBlt schneller ist...
    Daher sehe ich da auch keinen Sinn :)

    //Edit: Ach, ja. Wöfür gibt es denn den tollen

    Spoiler anzeigen


    Xeno? :)

  • Hi Mega,

    coole Funktion! Hab's mal in eine Bildschirmlupe 'umgebaut'.

    Spoiler anzeigen
    [autoit]

    #include <WindowsConstants.au3>
    #include <GUIConstants.au3>
    Opt('GUICloseOnESC', 1)
    Opt('GUIOnEventMode', 1)
    Opt("WinTitleMatchMode", 4)

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

    Global $shell = WinGetPos("classname=Shell_TrayWnd")
    Global $gui = GUICreate("Gui", 310, 310, @DesktopWidth - 310, @DesktopHeight - 310 - $shell[3], $WS_POPUP, $WS_EX_TOPMOST)
    GUISetState(@SW_SHOW)
    GUISetOnEvent($GUI_EVENT_CLOSE, "CLOSEClicked")

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

    While 1
    $pos_X = MouseGetPos(0)
    $pos_Y = MouseGetPos(1)
    Global $colors_A = _getPixelColors($pos_X - 75, $pos_Y - 75, $pos_X + 75, $pos_Y + 75)
    _paintPixel($colors_A, $gui, 5, 5)
    WEnd

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

    Func _getPixelColors($start_X = 0, $start_Y = 0, $end_X = @DesktopWidth, $end_Y = @DesktopHeight)
    Local $opt = Opt('ColorMode', 1)
    Local $coord[$end_X - $start_X][$end_Y - $start_Y]
    For $x = 0 To UBound($coord, 1) - 1
    For $y = 0 To UBound($coord, 2) - 1
    $coord[$x][$y] = PixelGetColor($x + $start_X, $y + $start_Y)
    Next
    Next
    Opt('ColorMode', $opt)
    Return $coord
    EndFunc ;==>_getPixelColors

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

    Func _paintPixel(ByRef $coord, $handle, $start_X = 0, $start_Y = 0)
    Local $dc = DllCall("user32.dll", "int", "GetDC", "hwnd", $handle)
    For $x = 0 To UBound($coord, 1) - 1
    For $y = 0 To UBound($coord, 2) - 1
    DllCall("gdi32.dll", "long", "SetPixel", "long", $dc[0], "long", ($x * 2) + $start_X, "long", ($y * 2) + $start_Y, "long", $coord[$x][$y])
    DllCall("gdi32.dll", "long", "SetPixel", "long", $dc[0], "long", ($x * 2) + $start_X + 1, "long", ($y * 2) + $start_Y, "long", $coord[$x][$y])
    DllCall("gdi32.dll", "long", "SetPixel", "long", $dc[0], "long", ($x * 2) + $start_X, "long", ($y * 2) + $start_Y + 1, "long", $coord[$x][$y])
    DllCall("gdi32.dll", "long", "SetPixel", "long", $dc[0], "long", ($x * 2) + $start_X + 1, "long", ($y * 2) + $start_Y + 1, "long", $coord[$x][$y])
    Next
    Next
    DllCall("user32.dll", "int", "ReleaseDC", "hwnd", 0, "int", $dc[0])
    Return $coord
    EndFunc ;==>_paintPixel

    [/autoit]
    • Offizieller Beitrag

    Hi,

    ich hatte es andersrum gemacht. Mit Lupe kannst du es viiel schneller machen.

    Spoiler anzeigen
    [autoit]

    #include<WindowsConstants.au3>
    #include<GUIConstantsEx.au3>
    Opt("WinTitleMatchMode", 4)
    Opt('GUICloseOnESC', 1)
    Opt('GUIOnEventMode', 1)

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

    $MagWidth = 150
    $MagHeight = 150
    $MagZoom = 1.00000000000000001
    Global $dll[3], $DeskHDC, $GUIHDC

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

    $dll[1] = DllOpen("user32.dll")
    $dll[2] = DllOpen("gdi32.dll")

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

    Global $shell = WinGetPos("classname=Shell_TrayWnd")
    Global $GUI = GUICreate("Gui", 160, 160, @DesktopWidth - 160, @DesktopHeight - 160 - $shell[3], $WS_POPUP, $WS_EX_TOPMOST)
    GUISetOnEvent($GUI_EVENT_CLOSE, "OnAutoItExit")
    GUISetState(@SW_SHOW)

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

    $DeskHDC = DllCall("user32.dll", "int", "GetDC", "hwnd", 0)
    $GUIHDC = DllCall("user32.dll", "int", "GetDC", "hwnd", $GUI)

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

    While 1
    MAG()
    Sleep(5)
    WEnd

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

    Func MAG()
    DllCall("gdi32.dll", "int", "StretchBlt", "int", $GUIHDC[0], "int", _
    0, "int", 0, "int", $MagWidth * $MagZoom, "int", $MagHeight * $MagZoom, "int", $DeskHDC[0], "int", _
    MouseGetPos(0) - $MagWidth / 2, "int", MouseGetPos(1) - $MagHeight / 2, "int", $MagWidth, "int", $MagHeight, _
    "long", $SRCCOPY)
    EndFunc ;==>MAG

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

    Func OnAutoItExit()
    DllCall("user32.dll", "int", "ReleaseDC", "int", $DeskHDC[0], "hwnd", 0)
    DllCall("user32.dll", "int", "ReleaseDC", "int", $GUIHDC[0], "hwnd", $GUI)
    DllClose($dll[1])
    DllClose($dll[2])
    Exit(0)
    EndFunc ;==>OnAutoItExit

    [/autoit]

    Oben kannst du auch deine Größe eintragen.

    Mega

  • Hi Mega,

    er meckert über '$SRCCOPY' die als globale Variable fehlt. Wenn ich sie anlege (also hinter '$GUIHDC') bleibt das Fenster schwarz. Hast du ne Idee wieso?

  • Okay, time for Update :D

    Edit : 8o So ist das fein! Schön schnell!

    Einmal editiert, zuletzt von JanSchmidt (12. Februar 2008 um 16:32)