Собственно понравилась идея создания масок и работа с ними из .ini, описанная тут: http://autoit-script.ru/index.php/topic,5107.msg69220.html, однако работать с чужой длл-кой не получилось, не совсем все понятно и работает ужасно нестабильно! Решил попробовать написать оное средствами AutoIt. Вот что вышло:
Вот содержание .ini:
Собственно, работает весьма неплохо, но есть несколько но:
1) скорость поиска приемлема только при узком диапазоне поиска и небольшом размере маски - прочесал форум в поисках более быстрой альтернативе пиксельсерчу, но однозначного решения не нашел...
2) при увеличении диапазона поиска по Х все ОК, но при увеличении диапазона по У перестает находить маску О_о, видимо что-то я перемудрил :(
П.С. после отлшифовки Масксерча сразу займусь генератором масок
П.П.С. надо будет еще добавить возможность пропускать пиксели (пометить в маске например "*") - в купе с генератором получится почти готовый эффективный ОКР =)
Код:
;собственно сама функция
Func MaskSearch ($MaskName, $x0, $y0, $x, $y, $NameINI)
Global $error = 1
Local $fNameINI = @ScriptDir & "\" & $NameINI
Local $cv = IniRead($fNameINI, $MaskName, "cv", "error") ;берем цвет из маски
If $cv = "error" Then
MsgBox (0, "Ошибка!", "ошибка чтения файла " & $NameINI & ", не найден параметр CV для" & $MaskName)
Exit
EndIf
Local $sh = IniRead($fNameINI, $MaskName, "sh", "error") ; берем погрешность
If $sh = "error" Then
MsgBox (0, "Ошибка!", "ошибка чтения файла " & $NameINI & ", не найден параметр SH для" & $MaskName)
Exit
EndIf
Local $i = 0, $j = 0
Local $str[100], $strX, $StrK, $Nstr, $Nstb, $mask[100] [100], $coord1[3], $XX = $x0, $YY = $y0, $coord1obs
; далее переводим нашу маску из построчного текста в двумерный массив, параллельно определяем размер маски и где находиться первый символ #
For $i = 1 To 100
Local $strK = IniRead($fNameINI, $MaskName, $i, "error") ; считываем построчно маску
If $strK = "error" Then ;если ошибка - значит строки закончились - находим число строк
$Nstr = $i-1
ExitLoop
Else ;до тех пор пока строки еще есть - каждую запоминаем в отдельную переменную
$str[$i] = $strK
EndIf
$strX = StringSplit ( $str[$i] , "") ;а теперь каждую строку разбиваем на отдельные символы
$Nstb = $strX[0] ;число столбцов
For $j = 1 To $Nstb ;теперь для удобства загоним все символы в двумерный массив
$mask [$i] [$j] = $strX [$j]
If $coord1[0] <> "Ok" Then ;тут мы находим первый символ #
If $mask [$i] [$j] = "#" Then
$coord1 [0] = "Ok"
$coord1 [1] = $j
$coord1 [2] = $i
EndIf
EndIf
Next
Next
;уф, дальше самое сложное
While $YY < ($y-$Nstr) ;перебираем каждый пиксель
While $XX < ($x-$Nstb)
$coord1obs = PixelSearch ($XX+$coord1[1]-1, $YY+$coord1[2]-1, $x-$Nstb+$coord1[1], $y-$Nstr+$coord1[2], $cv, $sh) ; собственно в начале ищем первый пиксель нужного цвета, в следующем цикле, если маска не будет найдена уже будем искать след. ближайшую точку с этим цветом (естественно проверять наличие маски во всех позициях просто смысла нет)
if Not @error Then ;как только нашли первый пиксель запускаем сравнение с маской
For $i = 1 To $Nstr
For $j = 1 To $Nstb
PixelSearch ($coord1obs[0] + $j - $coord1[1], $coord1obs[1] + $i - $coord1[2], $coord1obs[0] + $j - $coord1[1], $coord1obs[1] + $i - $coord1[2], $cv, $sh) ; начинаем проверять с учетом того, что наш первый пиксель нужного цвета не является первым в маске
If $mask [$i] [$j] = "#" Then ;тут ничего сложного = сравниваем найденный пиксель с аналогичным символом в маске
If Not @error Then ;если совпадает то идем дальше
If $i = $Nstr And $j = $Nstb Then ;если это последний символ в маске и все совпало - ура мы нашли маску - выводим координаты первого символа найденной маски
$error = 0
Return $coord1obs
EndIf
ContinueLoop
Else ;если символ не совпал, прекращаем сравнивать маску в данной позиции (идем на ХХ+1 и(или) УУ+1
ExitLoop(2)
EndIf
Else ;все тоже самое только уже мы не должны найти данный цвет в данном месте :)
If $mask [$i] [$j] = "-" Then
If @error Then
If $i = $Nstr And $j = $Nstb Then
$error = 0
Return $coord1obs
EndIf
ContinueLoop
Else
ExitLoop(2)
EndIf
Else ;если не нашли оба символа, значит маска записана некорректно
MsgBox (0, "Ошибка!", "ошибка чтения " & $NameINI & ", в маске " & $MaskName & " обнаружены неопознанные символы")
Exit
EndIf
EndIf
Next
Next
Else ;если не находим вообще ни одного пикселя нужного цвета, то вообще не сравниваем с маской а сразу выходим и выводим ошибку
$error = 1
Return 0
EndIf
$XX = $coord1obs[0]+1 ;это чтоб не перебирать все подряд, а только те позиции, которые нам подходят по первому искокому пикселю
WEnd
$YY = $coord1obs[1]+1
$XX = $x0
WEnd
;если все прочесав до сих пор не нашли совпадения - выводим в конце функции ошибку
$error = 1
Return 0
EndFunc
Global $coordMask = MaskSearch ("test2", 700, 50, 780, 230, "mask.ini") ;тут и вызываем нашу функцию с заданными параметрами: имя маски, область поиска и имя ини файла, если маску находим - получаем эррор=0 и координаты первого символа маски, иначе эррор=1 и вместо координат "0"
If $error = 0 Then
MouseMove ($coordMask[0], $coordMask[1])
MsgBox (0, "test", "маска найдена!")
Else
MsgBox (0, "test", "маска не найдена")
EndIf
Вот содержание .ini:
Код:
[test1]
cv = 0xFFFFFF
sh = 30
1 = ----
2 = -###
3 = -#--
[test2]
cv = 0xD4D5D5
sh = 30
1 = ----
2 = -###
3 = ----
4 = -###
5 = ----
1) скорость поиска приемлема только при узком диапазоне поиска и небольшом размере маски - прочесал форум в поисках более быстрой альтернативе пиксельсерчу, но однозначного решения не нашел...
2) при увеличении диапазона поиска по Х все ОК, но при увеличении диапазона по У перестает находить маску О_о, видимо что-то я перемудрил :(
П.С. после отлшифовки Масксерча сразу займусь генератором масок

П.П.С. надо будет еще добавить возможность пропускать пиксели (пометить в маске например "*") - в купе с генератором получится почти готовый эффективный ОКР =)