#include #include #include #include #include Global $threshold Global $image Global $width Global $height Global $pixels Global $pathString = "12345678" Global $scramble = False Global $rotate = 0 Global $speed ;; 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, "Erro", "Could not register the F10 hotkey.") Exit EndIf ;; Image dialog ;; $imageFile = FileOpenDialog ("Open image", @WorkingDir, "Images (*.jpg;*.jpeg;*.gif;*.png;*.bmp)", 1) If (@error) Then Exit ;; 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 () 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 GUIDelete ($optGUI) ExitLoop EndSwitch WEnd ;; 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 () ;; 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) ;; 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) $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 DllStructSetData ($bits, 1, $color, $index) Next 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 _WinAPI_ReleaseDC ($GUI, $dc) GUIRegisterMsg ($WM_PAINT, "OnPaint") ;; Ready to draw ;; TrayTip ("Pronto!", "Press F9 para draw. You can press F10 anytime to exit.", 10) HotKeySet ("{F9}", "Draw") HotKeySet ("{F10}", "Quit") While 1 Sleep (60000) WEnd Func OnPaint ($hwndGUI, $msgID, $wParam, $lParam) Local $paintStruct = DllStructCreate ("hwnd hdc;int fErase;dword rcPaint[4];int fRestore;int fIncUpdate;byte rgbReserved[32]") $dc = DllCall ("user32", "hwnd", "BeginPaint", "hwnd", $hwndGUI, "ptr", DllStructGetPtr ($paintStruct)) $dc = $dc[0] _WinAPI_BitBlt ($dc, 0, 0, $width, $height, $memDc, 0, 0, $SRCCOPY) DllCall ("user32", "hwnd", "EndPaint", "hwnd", $hwndGUI, "ptr", DllStructGetPtr ($paintStruct)) Return $GUI_RUNDEFMSG EndFunc Func Draw () $mouseCenter = MouseGetPos () $x0 = $mouseCenter[0] - ($width / 2) $y0 = $mouseCenter[1] - ($height / 2) ;; 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) ;; 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 ;; 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 Func DrawArea (ByRef $stack, $x, $y, $x0, $y0) Local $path[8] Local $continue $path = MakePath ($pathString) While 1 MouseMove ($x + $x0, $y + $y0, $speed) $pixels[$x][$y] = 2 If ($scramble) Then ScramblePath ($path) If ($rotate > 0) Then RotatePath ($path, $rotate) ;;;;;;;;;;;;;;;;;;; ;; +---+---+---+ ;; ;; | 1 | 2 | 3 | ;; ;; +---+---+---+ ;; ;; | 4 | | 5 | ;; ;; +---+---+---+ ;; ;; | 6 | 7 | 8 | ;; ;; +---+---+---+ ;; ;;;;;;;;;;;;;;;;;;; $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 Case 2 If ($y > 0) Then If ($pixels[$x][$y - 1] == 1) Then Push ($stack, $x, $y) $y -= 1 $continue = True ExitLoop EndIf EndIf 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 Case 4 If ($x > 0) Then If ($pixels[$x - 1][$y] == 1) Then Push ($stack, $x, $y) $x -= 1 $continue = True ExitLoop EndIf EndIf 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 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 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 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 If (Not Pop ($stack, $x, $y)) Then ExitLoop WEnd EndFunc Func MakePath ($string) Return StringSplit ($string, "") EndFunc Func ScramblePath (ByRef $path) Local $table = "12345678" Local $newPath[8] 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 $path = $newPath EndFunc 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 Func CreateStack ($size) Dim $stack[$size + 1][2] $stack[0][0] = 0 $stack[0][1] = $size Return $stack EndFunc 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 $stack[$stack[0][0]][0] = $x $stack[$stack[0][0]][1] = $y EndFunc Func Pop (ByRef $stack, ByRef $x, ByRef $y) If ($stack[0][0] < 1) Then Return False EndIf $x = $stack[$stack[0][0]][0] $y = $stack[$stack[0][0]][1] $stack[0][0] -= 1 Return True EndFunc Func Nothing () EndFunc Func Quit () MouseUp ("primary") Exit EndFunc