Что нового

[Автоматизация] Пример автоматизации рисования картинки в Paint

WSWR

AutoIT Гуру
Сообщения
941
Репутация
363
В "Столе заказов" был запрос на тему рисования в Paint, на основе примеров оттуда более-менее рабочий код, возможно, кому-нибудь пригодится)

Работает только в Win 7.

Скрипт создает массив пикселей, причем картинку преобразует в черно-белый вариант (т.е. рисовать будет одним цветом, ну, а в теории можно использовать до трех цветов, вроде так). Загружать лучше небольшие изображения - несколько сотен пикселей по высоте и ширине. Далее запускается Paint, и скрипт, используя данные из массива, перемещает мышь, и рисует картинку. Для выхода во время рисования - ESC.
При написании скрипта использовался пример преобразования картинки от Yashied-а и функция http://autoit-script.ru/index.php/topic,6462.0.html от XpycT-а.

Код:
#include <APIConstants.au3>
#include <Array.au3>
#include <GDIPlus.au3>
#include <WinAPIEx.au3>

If @OSVersion <> 'WIN_7' Then Exit

HotKeySet('{ESC}', '_Exit') ; выход из скрипта по ESC

Global $C = 1

$Array = _Matrix(@ScriptDir & '\0000.jpg')
If @error Then Exit

_Run()

Sleep(2000)

;~ _Mo1($Array) ; простое рисование
;~ _Mo2($Array) ; рисование со случайными линиями
_Mo3($Array) ; еще одно рисование со случайными линиями



Func _Matrix($sImagePath) ; получение массива пикселей из картинки
	If Not FileExists($sImagePath) Then Return SetError(1, 0, 0)

	_GDIPlus_Startup()
	$hImage = _GDIPlus_ImageLoadFromFile($sImagePath) 
	$hBitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hImage)
	
	Global $W = _GDIPlus_ImageGetWidth($hImage)
	Global $H = _GDIPlus_ImageGetHeight($hImage)

	_GDIPlus_ImageDispose($hImage)
	_GDIPlus_Shutdown()

	Dim $Matrix[$H / $C][$W / $C]
	Dim $HLS[3]

	$hSrcDC = _WinAPI_CreateCompatibleDC(0)
	$hSrcSv = _WinAPI_SelectObject($hSrcDC, $hBitmap)
	$hDstDC = _WinAPI_CreateCompatibleDC(0)
	$hDib = _WinAPI_CreateDIB(1, 1)
	$hDstSv = _WinAPI_SelectObject($hDstDC, $hDib)
	_WinAPI_SetStretchBltMode($hDstDC, $HALFTONE)

	For $y = 0 To $H / $C - 1
		For $x = 0 To $W / $C - 1
			_WinAPI_StretchBlt($hDstDC, 0, 0, 1, 1, $hSrcDC, $x * $C, $y * $C, $C, $C, $SRCCOPY)
			$RGB = _WinAPI_GetPixel($hDstDC, 0, 0)
			_WinAPI_ColorRGBToHLS($RGB, $HLS[0], $HLS[1], $HLS[2])
			$Matrix[$y][$x] = $HLS[1]
		Next
	Next

	_WinAPI_SelectObject($hSrcDC, $hSrcSv)
	_WinAPI_DeleteObject($hBitmap)
	_WinAPI_DeleteDC($hSrcDC)
	_WinAPI_SelectObject($hDstDC, $hDstSv)
	_WinAPI_DeleteObject($hDib)
	_WinAPI_DeleteDC($hDstDC)

	$Min = 240
	$Max = 0

	For $y = 0 To $H / $C - 1
		For $x = 0 To $W / $C - 1
			If $Min > $Matrix[$y][$x] Then
				$Min = $Matrix[$y][$x]
			EndIf
			If $Max < $Matrix[$y][$x] Then
				$Max = $Matrix[$y][$x]
			EndIf
		Next
	Next

	$Q = Round(($Min + $Max) / 2)

	For $y = 0 To $H / $C - 1
		For $x = 0 To $W / $C - 1
			$Matrix[$y][$x] = Number($Matrix[$y][$x] < $Q)
		Next
	Next
	;_ArrayDisplay($Matrix, 'Luminance')
	Return $Matrix
EndFunc   ;==>_Matrix

Func _Run() ; Запуск Paint
	Local $pos
	Run('mspaint.exe')
	WinActivate('[CLASS:MSPaintApp]', '')
	WinWaitActive('[CLASS:MSPaintApp]', '')
	WinSetOnTop('[CLASS:MSPaintApp]', '', 1)
	Opt('MouseCoordMode', 0)
	$pos = ControlGetPos('[CLASS:MSPaintApp]', '', '[CLASS:NetUIHWND; INSTANCE:1]')
	MouseMove($pos[0] + $pos[2] / 4, $pos[1] + $pos[3] + 100)
EndFunc   ;==>_Run

Func _Mo1($Matrix) ; простая функция рисования
	Local $pos, $x, $y
	$pos = MouseGetPos()
	For $y = 0 To $H / $C - 1
		For $x = 0 To $W / $C - 1
			If $Matrix[$y][$x] = 1 Then
				MouseMove($pos[0] + $x, $pos[1] + $y, 1)
				MouseClick('left')
			EndIf
		Next
	Next
EndFunc   ;==>_Mo1

Func _Mo2($Matrix) ; функция рисования со случайными линиями
	Local $pos, $x, $y
	$aRandom = _RandomEx(1, $H / $C, $H / $C, 1, 1)
	$pos = MouseGetPos()
	For $y = 1 To $H / $C
		For $x = 0 To $W / $C - 1
			If $Matrix[$aRandom[$y] - 1][$x] = 1 Then
				MouseMove($pos[0] + $x, $aRandom[$y] + $pos[1], 1)
				MouseClick('left')
			EndIf
		Next
	Next
EndFunc   ;==>_Mo2

Func _Mo3($Matrix) ; еще одна функция рисования со случайными линиями
	Local $pos, $x, $y
	$aRandom1 = _RandomEx(1, $H / $C, $H / $C, 1, 1)
	$aRandom2 = _RandomEx(1, $W / $C, $W / $C, 1, 1)
	$pos = MouseGetPos()
	For $y = 1 To $H / $C
		For $x = 1 To $W / $C
			If $Matrix[$aRandom1[$y] - 1][$aRandom2[$x] - 1] = 1 Then
				MouseMove($pos[0] + $aRandom2[$x], $aRandom1[$y] + $pos[1], 1)
				MouseClick('left')
			EndIf
		Next
	Next
EndFunc   ;==>_Mo3

Func _Exit()
	Exit
EndFunc   ;==>_Exit

; #FUNCTION# ==============================================================================================================
; Name...........: _RandomEx
; Description ...: Function generates a random numbers and displays them in a specified format.
; Syntax.........: _RandomEx($_iSNum, $_iENum, $_iRNumCount, $_iRetFormat, $_sRetDelimiter, $_iUnique)
; Parameters ....: $_iSNum         - The smallest number to be generated. The default is 0.
;                  $_iENum         - The largest number to be generated. The default is 1.
;                  $_iRNumCount    - Quantity of random numbers
;                  $_iRetFormat    - Return format (0 = String (Default), 1 = Array)
;                  $_sRetDelimiter - Random numbers delimeter if return format is string. The default is ","
;                  $_iUnique       - Specified if generated random numbers should be unique (0 = not unique, 1 = unique (Default))
; Return values .: Success - Return random numbers between $_iSNum and $_iENum in specified format.
;                  Failure - 0, sets @error  Returns 0 and sets @error flag to 1 if bad parameters
;                  |1 - $_iSNum equally or greater $_iENum
;                  |2 - Quantity of possible unique random numbers is less requested
; Author ........: XpycT, idea of return in string format madmasles http://autoit-script.ru/index.php/topic,6344.msg44489.html#msg44489
; =========================================================================================================================
Func _RandomEx($_iSNum = 0, $_iENum = 1, $_iRNumCount = 1, $_iUnique = 1, $_iRetFormat = 0, $_sRetDelimiter = ",")
	Local $sRNumStr = "`", $iNumCount = 0
	If $_iSNum >= $_iENum Then Return SetError(1, 0, 0)
	If $_iUnique And($_iENum - $_iSNum + 1) < $_iRNumCount Then Return SetError(2, 0, 0)
	While $iNumCount <> $_iRNumCount
		$iRNum = Random($_iSNum, $_iENum, 1)
		If $_iUnique = 1 Then
			If Not StringInStr($sRNumStr, "`" & $iRNum & "`") Then
				$sRNumStr &= $iRNum & "`"
				$iNumCount += 1
			EndIf
		Else
			$sRNumStr &= $iRNum & "`"

			$iNumCount += 1
		EndIf
	WEnd
	$sRNumStr = StringTrimLeft(StringTrimRight($sRNumStr, 1), 1)
	If $_iRetFormat = 0 Then Return StringReplace($sRNumStr, "`", $_sRetDelimiter)
	If $_iRetFormat = 1 Then Return StringSplit($sRNumStr, "`")
EndFunc   ;==>_RandomEx
 

mef-t

Осваивающий
Сообщения
306
Репутация
30
Немного ускорил 1 и 2 алгоритм рисования (в 2-3 раза)

Код:
#include <APIConstants.au3>
#include <Array.au3>
#include <GDIPlus.au3>
#include <WinAPIEx.au3>

;~ $hTimer = TimerInit() ; Запускает таймер и хранит дескриптор в переменной

If @OSVersion <> 'WIN_7' Then Exit

HotKeySet('{ESC}', '_Exit') ; выход из скрипта по ESC

Global $C = 1

$Array = _Matrix(@ScriptDir & '\0000.jpg')
If @error Then Exit

_Run()

Sleep(2000)

;~ _Mo1($Array) ; простое рисование
_Mo2($Array) ; рисование со случайными линиями
;~ _Mo3($Array) ; еще одно рисование со случайными линиями

;~ $iDiff = TimerDiff($hTimer) ; Возвращает разницу во времени, от предыдущего запуска TimerInit, дескриптор которого указан в переменной
;~ MsgBox(0, "Разница во времени", $iDiff)
Exit

Func _Matrix($sImagePath) ; получение массива пикселей из картинки
    If Not FileExists($sImagePath) Then Return SetError(1, 0, 0)

    _GDIPlus_Startup()
    $hImage = _GDIPlus_ImageLoadFromFile($sImagePath)
    $hBitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hImage)

    Global $W = _GDIPlus_ImageGetWidth($hImage)
    Global $H = _GDIPlus_ImageGetHeight($hImage)

    _GDIPlus_ImageDispose($hImage)
    _GDIPlus_Shutdown()

    Dim $Matrix[$H / $C][$W / $C]
    Dim $HLS[3]

    $hSrcDC = _WinAPI_CreateCompatibleDC(0)
    $hSrcSv = _WinAPI_SelectObject($hSrcDC, $hBitmap)
    $hDstDC = _WinAPI_CreateCompatibleDC(0)
    $hDib = _WinAPI_CreateDIB(1, 1)
    $hDstSv = _WinAPI_SelectObject($hDstDC, $hDib)
    _WinAPI_SetStretchBltMode($hDstDC, $HALFTONE)

    For $y = 0 To $H / $C - 1
        For $x = 0 To $W / $C - 1
            _WinAPI_StretchBlt($hDstDC, 0, 0, 1, 1, $hSrcDC, $x * $C, $y * $C, $C, $C, $SRCCOPY)
            $RGB = _WinAPI_GetPixel($hDstDC, 0, 0)
            _WinAPI_ColorRGBToHLS($RGB, $HLS[0], $HLS[1], $HLS[2])
            $Matrix[$y][$x] = $HLS[1]
        Next
    Next

    _WinAPI_SelectObject($hSrcDC, $hSrcSv)
    _WinAPI_DeleteObject($hBitmap)
    _WinAPI_DeleteDC($hSrcDC)
    _WinAPI_SelectObject($hDstDC, $hDstSv)
    _WinAPI_DeleteObject($hDib)
    _WinAPI_DeleteDC($hDstDC)

    $Min = 240
    $Max = 0

    For $y = 0 To $H / $C - 1
        For $x = 0 To $W / $C - 1
            If $Min > $Matrix[$y][$x] Then
                $Min = $Matrix[$y][$x]
            EndIf
            If $Max < $Matrix[$y][$x] Then
                $Max = $Matrix[$y][$x]
            EndIf
        Next
    Next

    $Q = Round(($Min + $Max) / 2)

    For $y = 0 To $H / $C - 1
        For $x = 0 To $W / $C - 1
            $Matrix[$y][$x] = Number($Matrix[$y][$x] < $Q)
        Next
    Next
    ;_ArrayDisplay($Matrix, 'Luminance')
    Return $Matrix
EndFunc   ;==>_Matrix

Func _Run() ; Запуск Paint
    Local $pos
    Run('mspaint.exe')
    WinActivate('[CLASS:MSPaintApp]', '')
    WinWaitActive('[CLASS:MSPaintApp]', '')
    WinSetOnTop('[CLASS:MSPaintApp]', '', 1)
    Opt('MouseCoordMode', 0)
    $pos = ControlGetPos('[CLASS:MSPaintApp]', '', '[CLASS:NetUIHWND; INSTANCE:1]')
    MouseMove($pos[0] + $pos[2] / 4, $pos[1] + $pos[3] + 100)
EndFunc   ;==>_Run

Func _Mo1($Matrix) ; простая функция рисования
    Local $pos, $x, $y
    $pos = MouseGetPos()
    For $y = 0 To $H / $C - 1
        For $x = 0 To $W / $C - 1
            If $Matrix[$y][$x] = 1 Then
                MouseMove($pos[0] + $x, $pos[1] + $y, 1)
;~                 MouseClick('left')
				MouseDown('left')
			Else
				MouseUp('left')
            EndIf
        Next
    Next
EndFunc   ;==>_Mo1

Func _Mo2($Matrix) ; функция рисования со случайными линиями
    Local $pos, $x, $y
    $aRandom = _RandomEx(1, $H / $C, $H / $C, 1, 1)
    $pos = MouseGetPos()
    For $y = 1 To $H / $C
        For $x = 0 To $W / $C - 1
            If $Matrix[$aRandom[$y] - 1][$x] = 1 Then
                MouseMove($pos[0] + $x, $aRandom[$y] + $pos[1], 1)
;~ 				MouseClick('left')
				MouseDown('left')
			Else
				MouseUp('left')
            EndIf
        Next
    Next
EndFunc   ;==>_Mo2

Func _Mo3($Matrix) ; еще одна функция рисования со случайными линиями
    Local $pos, $x, $y
    $aRandom1 = _RandomEx(1, $H / $C, $H / $C, 1, 1)
    $aRandom2 = _RandomEx(1, $W / $C, $W / $C, 1, 1)
    $pos = MouseGetPos()
    For $y = 1 To $H / $C
        For $x = 1 To $W / $C
            If $Matrix[$aRandom1[$y] - 1][$aRandom2[$x] - 1] = 1 Then
                MouseMove($pos[0] + $aRandom2[$x], $aRandom1[$y] + $pos[1], 1)
                MouseClick('left')
			EndIf
        Next
    Next
EndFunc   ;==>_Mo3

Func _Exit()
    Exit
EndFunc   ;==>_Exit

; #FUNCTION# ==============================================================================================================
; Name...........: _RandomEx
; Description ...: Function generates a random numbers and displays them in a specified format.
; Syntax.........: _RandomEx($_iSNum, $_iENum, $_iRNumCount, $_iRetFormat, $_sRetDelimiter, $_iUnique)
; Parameters ....: $_iSNum         - The smallest number to be generated. The default is 0.
;                  $_iENum         - The largest number to be generated. The default is 1.
;                  $_iRNumCount    - Quantity of random numbers
;                  $_iRetFormat    - Return format (0 = String (Default), 1 = Array)
;                  $_sRetDelimiter - Random numbers delimeter if return format is string. The default is ","
;                  $_iUnique       - Specified if generated random numbers should be unique (0 = not unique, 1 = unique (Default))
; Return values .: Success - Return random numbers between $_iSNum and $_iENum in specified format.
;                  Failure - 0, sets @error  Returns 0 and sets @error flag to 1 if bad parameters
;                  |1 - $_iSNum equally or greater $_iENum
;                  |2 - Quantity of possible unique random numbers is less requested
; Author ........: XpycT, idea of return in string format madmasles http://autoit-script.ru/index.php/topic,6344.msg44489.html#msg44489
; =========================================================================================================================
Func _RandomEx($_iSNum = 0, $_iENum = 1, $_iRNumCount = 1, $_iUnique = 1, $_iRetFormat = 0, $_sRetDelimiter = ",")
    Local $sRNumStr = "`", $iNumCount = 0
    If $_iSNum >= $_iENum Then Return SetError(1, 0, 0)
    If $_iUnique And($_iENum - $_iSNum + 1) < $_iRNumCount Then Return SetError(2, 0, 0)
    While $iNumCount <> $_iRNumCount
        $iRNum = Random($_iSNum, $_iENum, 1)
        If $_iUnique = 1 Then
            If Not StringInStr($sRNumStr, "`" & $iRNum & "`") Then
                $sRNumStr &= $iRNum & "`"
                $iNumCount += 1
            EndIf
        Else
            $sRNumStr &= $iRNum & "`"

            $iNumCount += 1
        EndIf
    WEnd
    $sRNumStr = StringTrimLeft(StringTrimRight($sRNumStr, 1), 1)
    If $_iRetFormat = 0 Then Return StringReplace($sRNumStr, "`", $_sRetDelimiter)
    If $_iRetFormat = 1 Then Return StringSplit($sRNumStr, "`")
EndFunc   ;==>_RandomEx
 
Автор
W

WSWR

AutoIT Гуру
Сообщения
941
Репутация
363
Увидел здесь http://autoit-script.ru/index.php?topic=10070.msg84145#msg84145
сообщение про функцию
Код:
_WinAPI_Mouse_Event

и далее про функцию _MouseClickFast отсюда
http://www.autoitscript.com/forum/topic/129149-mouseclickfast-mousemovefast/page__hl__%2B_winapi_mouse_event

Подумал, почему бы не проверить ее скорость в этой теме:
Код:
#include <APIConstants.au3>
#include <Array.au3>
#include <GDIPlus.au3>
#include <WinAPIEx.au3>

$hTimer = TimerInit() ; Запускает таймер и хранит дескриптор в переменной
If @OSVersion <> 'WIN_7' Then Exit

HotKeySet('{ESC}', '_Exit') ; выход из скрипта по ESC

Global $C = 1

$Array = _Matrix(@ScriptDir & '\12.bmp')
If @error Then Exit

_Run()

Sleep(2000)

;~ _Mo1($Array) ; простое рисование
_Mo3($Array) ; рисование со случайными линиями
;~ _Mo3($Array) ; еще одно рисование со случайными линиями

$iDiff = TimerDiff($hTimer) ; Возвращает разницу во времени, от предыдущего запуска TimerInit, дескриптор которого указан в переменной
MsgBox(0, "Разница во времени", $iDiff)

Func _Matrix($sImagePath) ; получение массива пикселей из картинки
    If Not FileExists($sImagePath) Then Return SetError(1, 0, 0)

    _GDIPlus_Startup()
    $hImage = _GDIPlus_ImageLoadFromFile($sImagePath) 
    $hBitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hImage)
    
    Global $W = _GDIPlus_ImageGetWidth($hImage)
    Global $H = _GDIPlus_ImageGetHeight($hImage)

    _GDIPlus_ImageDispose($hImage)
    _GDIPlus_Shutdown()

    Dim $Matrix[$H / $C][$W / $C]
    Dim $HLS[3]

    $hSrcDC = _WinAPI_CreateCompatibleDC(0)
    $hSrcSv = _WinAPI_SelectObject($hSrcDC, $hBitmap)
    $hDstDC = _WinAPI_CreateCompatibleDC(0)
    $hDib = _WinAPI_CreateDIB(1, 1)
    $hDstSv = _WinAPI_SelectObject($hDstDC, $hDib)
    _WinAPI_SetStretchBltMode($hDstDC, $HALFTONE)

    For $y = 0 To $H / $C - 1
        For $x = 0 To $W / $C - 1
            _WinAPI_StretchBlt($hDstDC, 0, 0, 1, 1, $hSrcDC, $x * $C, $y * $C, $C, $C, $SRCCOPY)
            $RGB = _WinAPI_GetPixel($hDstDC, 0, 0)
            _WinAPI_ColorRGBToHLS($RGB, $HLS[0], $HLS[1], $HLS[2])
            $Matrix[$y][$x] = $HLS[1]
        Next
    Next

    _WinAPI_SelectObject($hSrcDC, $hSrcSv)
    _WinAPI_DeleteObject($hBitmap)
    _WinAPI_DeleteDC($hSrcDC)
    _WinAPI_SelectObject($hDstDC, $hDstSv)
    _WinAPI_DeleteObject($hDib)
    _WinAPI_DeleteDC($hDstDC)

    $Min = 240
    $Max = 0

    For $y = 0 To $H / $C - 1
        For $x = 0 To $W / $C - 1
            If $Min > $Matrix[$y][$x] Then
                $Min = $Matrix[$y][$x]
            EndIf
            If $Max < $Matrix[$y][$x] Then
                $Max = $Matrix[$y][$x]
            EndIf
        Next
    Next

    $Q = Round(($Min + $Max) / 2)

    For $y = 0 To $H / $C - 1
        For $x = 0 To $W / $C - 1
            $Matrix[$y][$x] = Number($Matrix[$y][$x] < $Q)
        Next
    Next
    ;_ArrayDisplay($Matrix, 'Luminance')
    Return $Matrix
EndFunc   ;==>_Matrix

Func _Run() ; Запуск Paint
    Local $pos
    Run('mspaint.exe')
    WinActivate('[CLASS:MSPaintApp]', '')
    WinWaitActive('[CLASS:MSPaintApp]', '')
    WinSetOnTop('[CLASS:MSPaintApp]', '', 1)
    Opt('MouseCoordMode', 0)
    $pos = ControlGetPos('[CLASS:MSPaintApp]', '', '[CLASS:NetUIHWND; INSTANCE:1]')
    MouseMove($pos[0] + $pos[2] / 4, $pos[1] + $pos[3] + 100)
EndFunc   ;==>_Run

Func _Mo1($Matrix) ; простая функция рисования
    Local $pos, $x, $y
    $pos = MouseGetPos()
    For $y = 0 To $H / $C - 1
        For $x = 0 To $W / $C - 1
            If $Matrix[$y][$x] = 1 Then
            _MouseClickFast($pos[0] + $x, $pos[1] + $y)
			For $t= 1 To 10000			
			Next
			EndIf
        Next
    Next
EndFunc   ;==>_Mo1

Func _Mo2($Matrix) ; функция рисования со случайными линиями
    Local $pos, $x, $y
    $aRandom = _RandomEx(1, $H / $C, $H / $C, 1, 1)
    $pos = MouseGetPos()
    For $y = 1 To $H / $C
        For $x = 0 To $W / $C - 1
            If $Matrix[$aRandom[$y] - 1][$x] = 1 Then           
			_MouseClickFast($pos[0] + $x, $aRandom[$y] + $pos[1])
			For $t= 1 To 10000			
			Next			
			EndIf
        Next
    Next
EndFunc   ;==>_Mo2

Func _Mo3($Matrix) ; еще одна функция рисования со случайными линиями
    Local $pos, $x, $y
    $aRandom1 = _RandomEx(1, $H / $C, $H / $C, 1, 1)
    $aRandom2 = _RandomEx(1, $W / $C, $W / $C, 1, 1)
    $pos = MouseGetPos()
    For $y = 1 To $H / $C
        For $x = 1 To $W / $C
            If $Matrix[$aRandom1[$y] - 1][$aRandom2[$x] - 1] = 1 Then
            _MouseClickFast($pos[0] + $aRandom2[$x], $aRandom1[$y] + $pos[1])
			For $t= 1 To 10000			
			Next
			EndIf
        Next
    Next
EndFunc   ;==>_Mo3

Func _MouseClickFast($x, $y)
    $x = $x*65535/@DesktopWidth
    $y = $y*65535/@DesktopHeight
    _WinAPI_Mouse_Event(BitOR($MOUSEEVENTF_ABSOLUTE, $MOUSEEVENTF_MOVE), $x, $y)
    _WinAPI_Mouse_Event(BitOR($MOUSEEVENTF_ABSOLUTE, $MOUSEEVENTF_LEFTDOWN), $x, $y)
    _WinAPI_Mouse_Event(BitOR($MOUSEEVENTF_ABSOLUTE, $MOUSEEVENTF_LEFTUP), $x, $y)
EndFunc

Func _Exit()
    Exit
EndFunc   ;==>_Exit

; #FUNCTION# ==============================================================================================================
; Name...........: _RandomEx
; Description ...: Function generates a random numbers and displays them in a specified format.
; Syntax.........: _RandomEx($_iSNum, $_iENum, $_iRNumCount, $_iRetFormat, $_sRetDelimiter, $_iUnique)
; Parameters ....: $_iSNum         - The smallest number to be generated. The default is 0.
;                  $_iENum         - The largest number to be generated. The default is 1.
;                  $_iRNumCount    - Quantity of random numbers
;                  $_iRetFormat    - Return format (0 = String (Default), 1 = Array)
;                  $_sRetDelimiter - Random numbers delimeter if return format is string. The default is ","
;                  $_iUnique       - Specified if generated random numbers should be unique (0 = not unique, 1 = unique (Default))
; Return values .: Success - Return random numbers between $_iSNum and $_iENum in specified format.
;                  Failure - 0, sets @error  Returns 0 and sets @error flag to 1 if bad parameters
;                  |1 - $_iSNum equally or greater $_iENum
;                  |2 - Quantity of possible unique random numbers is less requested
; Author ........: XpycT, idea of return in string format madmasles http://autoit-script.ru/index.php/topic,6344.msg44489.html#msg44489
; =========================================================================================================================
Func _RandomEx($_iSNum = 0, $_iENum = 1, $_iRNumCount = 1, $_iUnique = 1, $_iRetFormat = 0, $_sRetDelimiter = ",")
    Local $sRNumStr = "`", $iNumCount = 0
    If $_iSNum >= $_iENum Then Return SetError(1, 0, 0)
    If $_iUnique And($_iENum - $_iSNum + 1) < $_iRNumCount Then Return SetError(2, 0, 0)
    While $iNumCount <> $_iRNumCount
        $iRNum = Random($_iSNum, $_iENum, 1)
        If $_iUnique = 1 Then
            If Not StringInStr($sRNumStr, "`" & $iRNum & "`") Then
                $sRNumStr &= $iRNum & "`"
                $iNumCount += 1
            EndIf
        Else
            $sRNumStr &= $iRNum & "`"

            $iNumCount += 1
        EndIf
    WEnd
    $sRNumStr = StringTrimLeft(StringTrimRight($sRNumStr, 1), 1)
    If $_iRetFormat = 0 Then Return StringReplace($sRNumStr, "`", $_sRetDelimiter)
    If $_iRetFormat = 1 Then Return StringSplit($sRNumStr, "`")
EndFunc   ;==>_RandomEx

В общем, получается где-то в 8 раз быстрее второго варианта от mef-t, пришлось для замедления даже добавить цикл For...Next, чтобы рисовало нормально, а не в каком-то абстрактном стиле) Мою тестовую картинку рисует за 17 секунд, а в предыдущем варианате за 140... Даже разницы между разными функциями уже не видно, как и самого процесса рисования - хаотичное дерганье курсора, и раз - картинка готова...
 

mef-t

Осваивающий
Сообщения
306
Репутация
30
Где-то в алгоритме ошибки, рисунок не совпадает с оригиналом. Множество лишних линий (как будто кнопку не отпустили).
 
Автор
W

WSWR

AutoIT Гуру
Сообщения
941
Репутация
363
mef-t

Там в функциях рисования нужно изменить в цикле
Код:
For $t = 1 To 10000          
Next

число, до которого цикл считается, например, вместо 10000 поставить 50000 или 100000, чтобы увеличить задержку.
 

mef-t

Осваивающий
Сообщения
306
Репутация
30
я так полагаю, что тут нужно выбрать как раз оптимальную задержку, т.к. она увеличивает время работы рисования.
Если маленькая - то возможны неточности, если большая - то уже долго.
Есть способ автоматического подбора правильного значения?
 
Автор
W

WSWR

AutoIT Гуру
Сообщения
941
Репутация
363
Скорее всего это прямо зависит от процессора, а его возможности трудно узнать.

Вообще, сначала-то все это должно было имитировать ручное рисование, т.е. сильно быстро и не нужно.
Можно сначала какой-нибудь расчет запускать, измерять время через TimerInit() и TimerDiff(), а потом по результату подставлять задержку.
 
Верх