GetPixelColor GDI?

  • So, nun brauch ich mal wieder eure Hilfe. Ich lade ein Bild mit GDI und möchte den Farbwert des Pixels x: 0 , y: 0 . Leider weiß ich nicht wie ich das zustande bringe.
    Weiß jemand ne Lösung?

    [autoit]


    $image = _GDIPlus_BitmapCreateFromFile(@ScriptDir & "\image.png")
    $color = ;Farbwert des oberen linken Pixels (zb:0xABCDEF)

    [/autoit]

    3 Mal editiert, zuletzt von Faweyr (27. März 2010 um 16:25)

  • [autoit]

    Func _GDIPlus_GetPixel($hBitmap,$X,$Y)
    ; Prog@ndy
    Local $result = DllCall($ghGDIPDLL, "int", "GdipBitmapGetPixel", "ptr", $hBitmap, "int", $X, "int", $Y, "dword*", 0)
    If @error Then Return SetError(1,0,0)
    Return SetError($result[0],1,$result[4])
    EndFunc
    Func _GDIPlus_SetPixel($hBitmap,$X,$Y, $ARGB)
    ; Prog@ndy
    Local $result = DllCall($ghGDIPDLL, "int", "GdipBitmapSetPixel", "ptr", $hBitmap, "int", $X, "int", $Y, "dword", $ARGB)
    If @error Then Return SetError(1,0,0)
    Return SetError($result[0],1,$result[0]=0)
    EndFunc

    [/autoit]


    ?

  • Warum machst du für das richtige Return einen SetError?

    Die hat Prog@ndy gemacht und nicht ich.

    ( Steht ja auch dran )

    Edit:

    Das SetError hat ja in diesem Fall auch ein Return, weil der 3 Parameter beim SetError angegeben ist. Steht genauer in der Hilfe.

  • Warum nicht einfach

    [autoit]

    Func _GDIPlus_GetPixel($hBitmap,$X,$Y)
    ; Prog@ndy
    Local $result = DllCall($ghGDIPDLL, "int", "GdipBitmapGetPixel", "ptr", $hBitmap, "int", $X, "int", $Y, "dword*", 0)
    If @error Then Return SetError(1,0,0)
    Return $result[4]
    EndFunc
    Func _GDIPlus_SetPixel($hBitmap,$X,$Y, $ARGB)
    ; Prog@ndy
    Local $result = DllCall($ghGDIPDLL, "int", "GdipBitmapSetPixel", "ptr", $hBitmap, "int", $X, "int", $Y, "dword", $ARGB)
    If @error Then Return SetError(1,0,0)
    Return
    EndFunc

    [/autoit]


    ?

    • Offizieller Beitrag

    Der Dll-Call könnte ohne Fehler aber trotzdem ohne Erfolg ausgeführt werden.
    @error gibt den Fehlerwert des Dll-Calls zurück - nicht die Erfolgskontrolle der Funktion.
    Ob die Funktion erfolgreich war ist im Returnwert des Dll-Call ablesbar. Meist ist $ret[0] = 0 für keinen Erfolg und > 0 für Erfolg (manchmal auch umgekehrt, ist in der jeweiligen Funktionsbeschreibung ersichtlich).
    Da standardmäßig @error=0 ist für Erfolg (bei AutoIt-Funktionen), wird hier der @error auf $ret[0] gesetzt. Dient zur Einsparung einer Codezeile.
    (Ich hoffe, ich hab das so richtig interpretiert)

  • [autoit]

    Func _GDIPlus_GetPixel($hBitmap,$X,$Y)
    ; Prog@ndy
    Local $result = DllCall($ghGDIPDLL, "int", "GdipBitmapGetPixel", "ptr", $hBitmap, "int", $X, "int", $Y, "dword*", 0)
    If @error Then Return SetError(1,0,0) ; Error, weil DllCall fehlgeschlagen ist
    Return SetError($result[0],1,$result[4]) ; Error, den die Dll-Funktion zurückliefert - Aus dem Errorcode kan mann ablesen, was genau jetzt falsch war...
    EndFunc

    [/autoit]
  • Eine Frage noch bei der Funktion "_GDIPlus_GetPixel" erhalte ich den Wert:

    [autoit]

    4284647137C

    [/autoit]


    nun würde ich gern wissen wie ich diesen in einen Farbwert umwandle, bzw was bedeutet die Zahl... ?(

  • Ich kenn mich damit nicht wirklich aus.
    Wenn ich den Wert mit _ColorGetRGB umwandle dann kommt 0 raus.
    Leider weiß ich somit nicht mehr weiter. Kann jemand helfen? ;(

  • Vielleicht hilft das, ist nicht von mir!

    Spoiler anzeigen
    [autoit]

    #include <GUIConstants.au3>
    #include <EditConstants.au3>
    #include <WindowsConstants.au3>
    #include <Color.au3>
    #include <WinAPI.au3>

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

    Global $threshold
    Global $image
    Global $width
    Global $height
    Global $pixels
    Global $pathString = "12345678"
    Global $scramble = False
    Global $rotate = 0
    Global $speed

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

    ;; Check hotkeys ;;
    If (Not HotKeySet ("{F9}", "Nothing")) Then
    MsgBox (16, "Error", "Could not register the F9 hotkey.")
    Exit
    EndIf
    If (Not HotKeySet ("{F10}", "Nothing")) Then
    MsgBox (16, "Error", "Could not register the F10 hotkey.")
    Exit
    EndIf

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

    ;; Image dialog ;;
    $imageFile = FileOpenDialog ("Open image", @WorkingDir, "Images (*.jpg;*.jpeg;*.gif;*.png;*.bmp)", 1)
    If (@error) Then Exit

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

    ;; Options dialog ;;
    $optGUI = GUICreate ("Settings", 160, 270, -1, -1, $WS_CAPTION, BitOr ($WS_EX_APPWINDOW, $WS_EX_TOOLWINDOW))
    GUICtrlCreateGroup ("Image processing", 5, 5, 150, 85)
    GUICtrlCreateLabel ("Sensitivity (0~255):", 10, 28, 110, 15)
    $thresholdInput = GUICtrlCreateInput ("100", 125, 25, 25, 20, $ES_NUMBER)
    GUICtrlCreateLabel ("Width (px):", 10, 48, 110, 15)
    $widthInput = GUICtrlCreateInput ("100", 125, 45, 25, 20, $ES_NUMBER)
    GUICtrlCreateLabel ("Height (px):", 10, 68, 110, 15)
    $heightInput = GUICtrlCreateInput ("100", 125, 65, 25, 20, $ES_NUMBER)
    GUICtrlCreateGroup ("Drawing pattern", 5, 95, 150, 140)
    $horizontalRadio = GUICtrlCreateRadio ("Horizontal", 10, 115, 110, 15)
    $verticalRadio = GUICtrlCreateRadio ("Vertical", 10, 135, 110, 15)
    $diagonalRadio = GUICtrlCreateRadio ("Diagonal", 10, 155, 110, 15)
    $rotateRadio = GUICtrlCreateRadio ("Spiral", 10, 175, 110, 15)
    $scrambleRadio = GUICtrlCreateRadio ("Random", 10, 195, 110, 15)
    GUICtrlSetState ($diagonalRadio, $GUI_CHECKED)
    GUICtrlCreateLabel ("Mouse speed (0~100):", 10, 213, 110, 15)
    $speedInput = GUICtrlCreateInput ("0", 125, 210, 25, 20, $ES_NUMBER)
    $okBtn = GUICtrlCreateButton ("Ok", 30, 245, 40, 20)
    $cancelBtn = GUICtrlCreateButton ("Cancel", 80, 245, 50, 20)
    GUISetState ()

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

    While 1
    Switch (GUIGetMsg ())
    Case $GUI_EVENT_CLOSE
    Exit
    Case $cancelBtn
    Exit
    Case $okBtn
    $threshold = GUICtrlRead ($thresholdInput)
    $width = GUICtrlRead ($widthInput)
    $height = GUICtrlRead ($heightInput)
    $speed = GUICtrlRead ($speedInput)
    If (GUICtrlRead ($horizontalRadio) == $GUI_CHECKED) Then
    $pathString = "45273618"
    ElseIf (GUICtrlRead ($verticalRadio) == $GUI_CHECKED) Then
    $pathString = "27453618"
    ElseIf (GUICtrlRead ($diagonalRadio) == $GUI_CHECKED) Then
    $pathString = "36184527"
    ElseIf (GUICtrlRead ($rotateRadio) == $GUI_CHECKED) Then
    $pathString = "14678532"
    $rotate = 1
    ElseIf (GUICtrlRead ($scrambleRadio) == $GUI_CHECKED) Then
    $scramble = True
    EndIf

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

    GUIDelete ($optGUI)
    ExitLoop
    EndSwitch
    WEnd

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

    ;; Processing dialog ;;
    $GUI = GUICreate ("Processing image...", $width, $height + 20, -1, -1, $WS_CAPTION, BitOr ($WS_EX_APPWINDOW, $WS_EX_TOOLWINDOW))
    GUISetBkColor (0xffffff)
    $imageBox = GUICtrlCreatePic ($imageFile, 0, 0, $width, $height)
    $progress = GUICtrlCreateProgress (0, $height, $width, 20)
    GUISetState ()

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

    ;; Get image pixels ;;
    $dc = _WinAPI_GetDC ($GUI)
    $memDc = _WinAPI_CreateCompatibleDC ($dc)
    $bitmap = _WinAPI_CreateCompatibleBitmap ($dc, $width, $height)
    _WinAPI_SelectObject ($memDc, $bitmap)
    _WinAPI_BitBlt ($memDc, 0, 0, $width, $height, $dc, 0, 0, $SRCCOPY)
    $bits = DllStructCreate ("dword[" & ($width * $height) & "]")
    DllCall ("gdi32", "int", "GetBitmapBits", "ptr", $bitmap, "int", ($width * $height * 4), "ptr", DllStructGetPtr ($bits))
    GUICtrlDelete ($imageBox)

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

    ;; Process the pixels ;;
    Dim $pixels[$width][$height]
    For $y = 0 To ($height - 1)
    For $x = 0 To ($width - 1)
    $index = ($y * $width) + $x
    $color = DllStructGetData ($bits, 1, $index)

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

    $red = _ColorGetBlue ($color)
    $green = _ColorGetGreen ($color)
    $blue = _ColorGetRed ($color)
    $shade = ($red + $green + $blue) / 3
    If ($shade > $threshold) Then
    $color = 0xffffff
    $pixels[$x][$y] = 0
    Else
    $color = 0
    $pixels[$x][$y] = 1
    EndIf

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

    DllStructSetData ($bits, 1, $color, $index)
    Next

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

    DllCall ("gdi32", "int", "SetBitmapBits", "ptr", $bitmap, "int", ($width * $height * 4), "ptr", DllStructGetPtr ($bits))
    _WinAPI_BitBlt ($dc, 0, 0, $width, $height, $memDc, 0, 0, $SRCCOPY)
    GUICtrlSetData ($progress, ($y * 100) / $height)
    Next

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

    _WinAPI_ReleaseDC ($GUI, $dc)
    GUIRegisterMsg ($WM_PAINT, "OnPaint")

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

    ;; Ready to draw ;;
    TrayTip ("Fast!", "Press F9 for draw. You can press F10 anytime to exit.", 10)
    HotKeySet ("{F9}", "Draw")
    HotKeySet ("{F10}", "Quit")

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

    While 1
    Sleep (60000)
    WEnd

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

    Func OnPaint ($hwndGUI, $msgID, $wParam, $lParam)
    Local $paintStruct = DllStructCreate ("hwnd hdc;int fErase;dword rcPaint[4];int fRestore;int fIncUpdate;byte rgbReserved[32]")

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

    $dc = DllCall ("user32", "hwnd", "BeginPaint", "hwnd", $hwndGUI, "ptr", DllStructGetPtr ($paintStruct))
    $dc = $dc[0]

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

    _WinAPI_BitBlt ($dc, 0, 0, $width, $height, $memDc, 0, 0, $SRCCOPY)

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

    DllCall ("user32", "hwnd", "EndPaint", "hwnd", $hwndGUI, "ptr", DllStructGetPtr ($paintStruct))
    Return $GUI_RUNDEFMSG
    EndFunc

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

    Func Draw ()

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

    ;~ Run("mspaint.exe","",@SW_MAXIMIZE)
    ;~ Sleep(5000)
    ;~ MouseMove(@DesktopWidth/2, @DesktopHeight/2)

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

    $mouseCenter = MouseGetPos ()
    $x0 = $mouseCenter[0] - ($width / 2)
    $y0 = $mouseCenter[1] - ($height / 2)

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

    ;; Move the mouse around the drawing perimeter ;;
    MouseMove ($x0, $y0)
    MouseMove ($x0 + $width, $y0)
    MouseMove ($x0 + $width, $y0 + $height)
    MouseMove ($x0, $y0 + $height)
    MouseMove ($x0, $y0)

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

    ;; Draw all the areas ;;
    $stack = CreateStack (1000)
    For $y = 0 To ($height - 1)
    For $x = 0 To ($width - 1)
    If ($pixels[$x][$y] == 1) Then
    MouseMove ($x + $x0, $y + $y0, $speed)
    MouseDown ("primary")
    DrawArea ($stack, $x, $y, $x0, $y0)
    MouseUp ("primary")
    Else
    EndIf
    Next
    Next

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

    ;; Reset the pixels statuses ;;
    For $y = 0 To ($height - 1) Step 1
    For $x = 0 To ($width - 1) Step 1
    If ($pixels[$x][$y] == 2) Then
    $pixels[$x][$y] = 1
    EndIf
    Next
    Next
    EndFunc

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

    Func DrawArea (ByRef $stack, $x, $y, $x0, $y0)
    Local $path[8]
    Local $continue

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

    $path = MakePath ($pathString)

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

    While 1
    MouseMove ($x + $x0, $y + $y0, $speed)
    $pixels[$x][$y] = 2

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

    If ($scramble) Then ScramblePath ($path)
    If ($rotate > 0) Then RotatePath ($path, $rotate)

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

    ;;;;;;;;;;;;;;;;;;;
    ;; +---+---+---+ ;;
    ;; | 1 | 2 | 3 | ;;
    ;; +---+---+---+ ;;
    ;; | 4 | | 5 | ;;
    ;; +---+---+---+ ;;
    ;; | 6 | 7 | 8 | ;;
    ;; +---+---+---+ ;;
    ;;;;;;;;;;;;;;;;;;;

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

    $continue = False
    For $i = 0 To 7
    Switch ($path[$i])
    Case 1
    If (($x > 0) And ($y > 0)) Then
    If ($pixels[$x - 1][$y - 1] == 1) Then
    Push ($stack, $x, $y)
    $x -= 1
    $y -= 1
    $continue = True
    ExitLoop
    EndIf
    EndIf

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

    Case 2
    If ($y > 0) Then
    If ($pixels[$x][$y - 1] == 1) Then
    Push ($stack, $x, $y)
    $y -= 1
    $continue = True
    ExitLoop
    EndIf
    EndIf

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

    Case 3
    If (($x > 0) And ($y < 0)) Then
    If ($pixels[$x + 1][$y - 1] == 1) Then
    Push ($stack, $x, $y)
    $x += 1
    $y -= 1
    $continue = True
    ExitLoop
    EndIf
    EndIf

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

    Case 4
    If ($x > 0) Then
    If ($pixels[$x - 1][$y] == 1) Then
    Push ($stack, $x, $y)
    $x -= 1
    $continue = True
    ExitLoop
    EndIf
    EndIf

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

    Case 5
    If ($x < ($width - 1)) Then
    If ($pixels[$x + 1][$y] == 1) Then
    Push ($stack, $x, $y)
    $x += 1
    $continue = True
    ExitLoop
    EndIf
    EndIf

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

    Case 6
    If (($x < 0) And ($y > 0)) Then
    If ($pixels[$x - 1][$y + 1] == 1) Then
    Push ($stack, $x, $y)
    $x -= 1
    $y += 1
    $continue = True
    ExitLoop
    EndIf
    EndIf

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

    Case 7
    If ($y < ($height - 1)) Then
    If ($pixels[$x][$y + 1] == 1) Then
    Push ($stack, $x, $y)
    $y += 1
    $continue = True
    ExitLoop
    EndIf
    EndIf

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

    Case 8
    If (($x < ($width - 1)) And ($y < ($height - 1))) Then
    If ($pixels[$x + 1][$y + 1] == 1) Then
    Push ($stack, $x, $y)
    $x += 1
    $y += 1
    $continue = True
    ExitLoop
    EndIf
    EndIf
    EndSwitch
    Next
    If ($continue) Then ContinueLoop

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

    If (Not Pop ($stack, $x, $y)) Then ExitLoop
    WEnd
    EndFunc

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

    Func MakePath ($string)
    Return StringSplit ($string, "")
    EndFunc

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

    Func ScramblePath (ByRef $path)
    Local $table = "12345678"
    Local $newPath[8]

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

    For $i = 8 To 1 Step -1
    $next = StringMid ($table, Random (1, $i, 1), 1)
    $newPath[$i - 1] = Number ($next)
    $table = StringReplace ($table, $next, "")
    Next

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

    $path = $newPath
    EndFunc

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

    Func RotatePath (Byref $path, $places)
    If ($places == 0) Then
    Return $path
    Else
    For $i = 1 To Abs ($places)
    $temp = $path[7]
    $path[7] = $path[6]
    $path[6] = $path[5]
    $path[5] = $path[4]
    $path[4] = $path[3]
    $path[3] = $path[2]
    $path[2] = $path[1]
    $path[1] = $path[0]
    $path[0] = $temp
    Next
    EndIf
    EndFunc

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

    Func CreateStack ($size)
    Dim $stack[$size + 1][2]
    $stack[0][0] = 0
    $stack[0][1] = $size
    Return $stack
    EndFunc

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

    Func Push (ByRef $stack, $x, $y)
    $stack[0][0] += 1
    If ($stack[0][0] > $stack[0][1]) Then
    $stack[0][1] += 1000
    ReDim $stack[$stack[0][1] + 1][2]
    EndIf

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

    $stack[$stack[0][0]][0] = $x
    $stack[$stack[0][0]][1] = $y
    EndFunc

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

    Func Pop (ByRef $stack, ByRef $x, ByRef $y)
    If ($stack[0][0] < 1) Then
    Return False
    EndIf

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

    $x = $stack[$stack[0][0]][0]
    $y = $stack[$stack[0][0]][1]

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

    $stack[0][0] -= 1
    Return True
    EndFunc

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

    Func Nothing ()
    EndFunc

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

    Func Quit ()
    MouseUp ("primary")
    Exit
    EndFunc

    [/autoit]
  • Das hier ist ein kleines Beispiel (muss natürlich noch angepasst werden):

    Spoiler anzeigen
    [autoit]

    #include <GDIPlus.au3>
    #include <Color.au3>

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

    _GDIPlus_Startup()

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

    $Bitmap = _GDIPlus_ImageLoadFromFile("Bild.jpg")
    $CLSID = _GDIPlus_EncodersGetCLSID("JPG")
    $x = 0
    $y = 0
    $Color = _GDIPlus_GetPixel($Bitmap, $x, $y)
    $HexColor = "0x"&Hex($color)
    $R=_ColorGetRed($HexColor)
    $G=_ColorGetGreen($HexColor)
    $B=_ColorGetBlue($HexColor)

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

    MsgBox(0,"Farbe:","Rot: "&@TAB&@TAB&$R&@CRLF&"Grün: "&@TAB&@TAB&$G&@CRLF&"Blau: "&@TAB&@TAB&$B&@CRLF&"Hex-Gesamtfarbe: "&@TAB&"0x"&Hex($R,2)&Hex($G,2)&Hex($B,2))

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

    Func _GDIPlus_GetPixel($hBitmap,$X,$Y)
    ; Prog@ndy
    Local $result = DllCall($ghGDIPDLL, "int", "GdipBitmapGetPixel", "ptr", $hBitmap, "int", $X, "int", $Y, "dword*", 0)
    If @error Then Return SetError(1,0,0)
    Return SetError($result[0],1,$result[4])
    EndFunc
    Func _GDIPlus_SetPixel($hBitmap,$X,$Y, $ARGB)
    ; Prog@ndy
    Local $result = DllCall($ghGDIPDLL, "int", "GdipBitmapSetPixel", "ptr", $hBitmap, "int", $X, "int", $Y, "dword", $ARGB)
    If @error Then Return SetError(1,0,0)
    Return SetError($result[0],1,$result[0]=0)
    EndFunc

    [/autoit]

    Wer immer nur das tut, was er bereits kann - wird auch immer nur das bleiben, was er bereits ist!

  • Hey, danke. Darauf kam ich nicht...hab erst den Rot,Grün,Blauwert davon genommen und dann Hex davon...aber das ging ja wie gesagt nicht.
    Toole Lösung...vielen Dank. :thumbup: