--lua
local ffi=require "ffi"
local rmem=ffi.cast
local C=ffi.C
local SRCCOPY = 0x00CC0020
local DIB_RGB_COLORS = 0
local BI_RGB = 0
ffi.cdef[[
typedef long LONG;
typedef unsigned short WORD;
typedef unsigned long DWORD;
typedef unsigned char BYTE;
typedef void *LPVOID;
typedef struct {DWORD biSize; LONG biWidth; LONG biHeight; WORD biPlanes; WORD biBitCount; DWORD biCompression; DWORD biSizeImage;
LONG biXPelsPerMeter; LONG biYPelsPerMeter; DWORD biClrUsed; DWORD biClrImportant;} BITMAPINFOHEADER;
typedef struct {BYTE rgbBlue; BYTE rgbGreen; BYTE rgbRed; BYTE rgbReserved;} RGBQUAD;
typedef struct {BITMAPINFOHEADER bmiHeader; RGBQUAD bmiColors[1];} BITMAPINFO;
int GetDC(int hWnd);
int ReleaseDC(int hWnd, int hDC);
int SelectObject(int hdc, int h);
int CreateCompatibleDC(int hdc);
int CreateCompatibleBitmap(int hdc, int cx, int cy);
bool DeleteObject(int ho);
bool BitBlt(int hdc, int x, int y, int cx, int cy, int hdcSrc, int x1, int y1, unsigned long rop);
int GetDIBits(int hdc, int hbm, unsigned int start, unsigned int cLines, LPVOID lpvBits, BITMAPINFO* lpbmi, unsigned int usage);
void free(void *ptr);
void *malloc(size_t size);
]]
local ext = {}
local internal = {}
local images = {}
ext.wait = {} -- блок дейстивий по ожиданию цвета/изображений/кликов/окон.
ext.wait.log = 1 -- включить ввывод description в лог.
ext.wait.log_level = 2 -- уровень логирования для description.
ext.lg_level = 1 -- уровень логирования. Для вывода сообщения должен быть больше или равен
-- заданному при вызове функции.
-- Если при вызове функции уровень не задан, то он считается равным 0.
function ext.lg(data, comment, level)
if (not level and ext.lg_level < 0) or (level and level < ext.lg_level) then
return
end
if comment ~= nil then
log(comment)
end
local tab = ""
local deep = 0
local function show(data)
-- Пишем в лог комментарий.
deep = deep + 1 -- Уровень вложенности вызовов функции.
if type(data) == "table" then
local element_counter = 0
for k,v in pairs(data) do
element_counter = element_counter + 1
if type (v) == "table" then
log(tab..'table: '..tostring(k))
tab = tab .. " "
show(v)
tab = string.sub(tab, 1, -5)
else
if type(v) == "nil" then v = "nil"
elseif type(v) == "string" then v = '"' .. v .. '"'
elseif type(v) == "number" then v = tostring(v)
elseif type(v) == "function" then v = tostring(v)
elseif type(v) == "thread" then v = tostring(v)
elseif type(v) == "userdata" then v = "userdata"
elseif type(v) == "boolean" then v = tostring(v)
elseif type(v) == "table" then
log(tab..""..k.." = "..v or "nil")
else
v = "uknown data type"
end
log(tab..""..k.." = " .. v)
end
end
log(tab.."".."Elements in table: " .. element_counter)
else
log('table is "' .. type(data) .. '" data type. Value: ' .. tostring(data))
end
--tab = ""
--deep = 0
end
show(data)
end
ext.getimage = function(x1, y1, x2, y2, handle, abs_flag)
if handle > 2 or handle == 0 then
local a, w, h, l
w = x2-x1 + 1
h = y2-y1 + 1
local hdcWindow = C.GetDC(handle or 0) -- если хендл не указан, то получим скрин с экрана
local hdcMemDC = C.CreateCompatibleDC(hdcWindow)
local hbmScreen = C.CreateCompatibleBitmap(hdcWindow, w, h)
C.SelectObject(hdcMemDC,hbmScreen)
C.BitBlt(hdcMemDC, 0, 0, w, h, hdcWindow, x1, y1, SRCCOPY) -- сохранить в памяти скрин с окна или экрана
local bi = ffi.new('BITMAPINFO', { {ffi.sizeof('BITMAPINFOHEADER'), w, -h, 1, 24, BI_RGB,0,0,0,0,0} })
C.GetDIBits(hdcWindow, hbmScreen, 0, h, nil, bi, DIB_RGB_COLORS) -- узнать какого размера нужен массив
local bitmap_address = ffi.gc(C.malloc(bi.bmiHeader.biSizeImage), C.free)
local h_copied = C.GetDIBits(hdcWindow, hbmScreen, 0, h, bitmap_address, bi, DIB_RGB_COLORS) -- получить битовый массив
--return h_copied and ffi.cast("int", bitmap_address) or nil, w, h_copied, math.floor(w*3/4+0.75)*4
if h_copied > 0 then
a = tonumber(ffi.cast("int", bitmap_address))
images[a] = {}
images[a].handle = handle
images[a].hdcWindow = hdcWindow
images[a].hdcMemDC = hdcMemDC
images[a].hbmScreen = hbmScreen
images[a].bitmap_address = bitmap_address
return a, w, h_copied, math.floor(w*3/4+0.75)*4
else
return nil
end
else
return internal.getimage_orig(x1, y1, x2, y2, handle, abs_flag)
end
end
internal.deleteimage_orig = deleteimage
ext.deleteimage = function(address)
if images[address] then
C.ReleaseDC(images[address].handle, images[address].hdcWindow)
C.DeleteObject(images[address].hdcMemDC)
C.DeleteObject(images[address].hbmScreen)
ffi.C.free(ffi.gc(images[address].bitmap_address, nil)) -- Manually free the memory
images[address] = nil
else
deleteimage_orig(address)
end
end
-- Раскладывает код цвета на отдельные каналы.
ext.color_to_rgb = function(c)
local r,g,b
b = math.floor(c/65536)
g = math.floor(c/256-b*256)
r = c-b*256*256-g*256
return r, g ,b
end
ext.color_to_bgr = function(c)
local r,g,b
b = math.floor(c/65536)
g = math.floor(c/256-b*256)
r = c-b*256*256-g*256
return b, g, r
end
ext.rgb_to_color = function(r, g, b)
return b*256*256 + g*256 + r
end
ext.bgr_to_color = function(b, g, r)
return b*256*256 + g*256 + r
end
-- ВНИМАНИЕ ФИКС СТАНДАРТНОЙ ФУНКИИ
-- ОРИГИНАЛЬНАЯ ФУНКЦИЯ ПОЛНОСТЬЮ ЗАМЕНЕНА
colortorgb = ext.color_to_rgb
internal.color_deviation_parse = function(b1, g1, r1, b2, g2, r2)
if type(b1) == "table" then
else
end
if not g1 then
g1 = b1
r1 = b1
b2 = b1
g2 = b1
r2 = b1
elseif not b2 then
b2 = b1
g2 = g1
r2 = r1
else
-- Ставим минимальные значения вначале, максимальные вконце.
b1, g1, r1, b2, g2, r2 = b2, g2, r2, b1, g1, r1
end
return b1, g1, r1, b2, g2, r2
end
--[[==
internal.color_deviation_parse = function(c1, c2, b1, g1, r1, b2, g2, r2)
if type(b1) == "table" then
if type(g1) == "table" then
b2 = g1[1]
g2 = g1[2]
r2 = g1[3]
else
r2 = b2
g2 = r1
b2 = g1
end
r1 = b1[3]
g1 = b1[2]
b1 = b1[1]
elseif type(b2) == "table" then
r2 = b2[3]
g2 = b2[2]
b2 = b2[1]
elseif not g1 and not r1 and not b2 and not g2 and not r2 then
g1 = b1
r1 = b1
b2 = b1
g2 = b1
r2 = b1
end
if not b2 and not g2 and not r2 then
r2 = r1
g2 = g1
b2 = b1
end
local c1r, c1g, c1b
c1b = math.floor(c1/65536)
c1g = math.floor(c1/256-c1b*256)
c1r = c1-c1b*256*256-c1g*256
local c2r, c2g, c2b
c2b = math.floor(c2/65536)
c2g = math.floor(c2/256-c2b*256)
c2r = c2-c2b*256*256-c2g*256
return b1, g1, r1, b2, g2, r2, c1r, c1g, c1b, c2r, c2g, c2b
end
]]
internal.color_deviation_a = function(c1b1, c1g1, c1r1, c1b2, c1g2, c1r2, c2b, c2g, c2r, b1, g1, r1, b2, g2, r2)
if c1r1 - b1 <= c2r and c1g1 - g1 <= c2g and c1b1 - r1 <= c2b and
c1r2 + b2 >= c2r and c1g2 + g2 >= c2g and c1b2 + r2 >= c2b then
return true
else
return false
end
end
internal.color_deviation_r = function(c1b1, c1g1, c1r1, c1b2, c1g2, c1r2, c2b, c2g, c2r, b1, g1, r1, b2, g2, r2)
local r1d = math.ceil(c1r1 * r1 * 0.01)
local g1d = math.ceil(c1g1 * g1 * 0.01)
local b1d = math.ceil(c1b1 * b1 * 0.01)
local r2d = math.ceil(c1r2 * r2 * 0.01)
local g2d = math.ceil(c1g2 * g2 * 0.01)
local b2d = math.ceil(c1b2 * b2 * 0.01)
if c1r1 - r1d <= c2r and c1g1 - g1d <= c2g and c1b1 - b1d <= c2b and
c1r2 + r2d >= c2r and c1g2 + g2d >= c2g and c1b2 + b2d >= c2b then
return true
else
return false
end
end
internal.color_deviation_s = function(c1b1, c1g1, c1r1, c1b2, c1g2, c1r2, c2b, c2g, c2r, br1, rg1, gb1, br2, rg2, gb2)
c1b1, c1g1, c1r1, c1b2, c1g2, c1r2, c2b, c2g, c2r = c1b1+1, c1g1+1, c1r1+1, c1b2+1, c1g2+1, c1r2+1, c2b+1, c2g+1, c2r+1
local c1br1 = c1b1/c1r1
local c1rg1 = c1r1/c1g1
local c1gb1 = c1g1/c1b1
local c1br2 = c1b2/c1r2
local c1rg2 = c1r2/c1g2
local c1gb2 = c1g2/c1b2
local br_d1 = c1br1 * br1 * 0.01
local rg_d1 = c1rg1 * rg1 * 0.01
local gb_d1 = c1gb1 * gb1 * 0.01
local br_d2 = c1br2 * br2 * 0.01
local rg_d2 = c1rg2 * rg2 * 0.01
local gb_d2 = c1gb2 * gb2 * 0.01
local c2br = c2b/c2r
local c2rg = c2r/c2g
local c2gb = c2g/c2b
--[[
log(
"", c1b1, c1g1, c1r1, "\r\n",
c1b2, c1g2, c1r2, "\r\n",
c2b, c2g, c2r
)
log(
"", c1br1, c1rg1, c1gb1, "\r\n",
c1br2, c1rg2, c1gb2, "\r\n",
c2br, c2rg, c2gb
)
log(
"", c1br1 , br_d1 , c2br , c1rg1 , rg_d1 , c2rg , c1gb1 , gb_d1 , c2gb , "\r\n",
c1br2 , br_d2 , c2br , c1rg2 , rg_d2 , c2rg , c1gb2 , gb_d2 , c2gb
)
log(
"", tostring(c1br1 - br_d1 <= c2br) , tostring(c1rg1 - rg_d1 <= c2rg) , tostring(c1gb1 - gb_d1 <= c2gb) , "\r\n",
tostring(c1br2 + br_d2 >= c2br) , tostring(c1rg2 + rg_d2 >= c2rg) , tostring(c1gb2 + gb_d2 >= c2gb)
)
log(
"", c1br1 - br_d1 ,"<=", c2br , c1rg1 - rg_d1 ,"<=", c2rg , c1gb1 - gb_d1 ,"<=", c2gb , "\r\n",
c1br2 + br_d2 ,">=", c2br , c1rg2 + rg_d2 ,">=", c2rg , c1gb2 + gb_d2 ,">=", c2gb
)
]]
if c1br1 - br_d1 <= c2br and c1rg1 - rg_d1 <= c2rg and c1gb1 - gb_d1 <= c2gb and
c1br2 + br_d2 >= c2br and c1rg2 + rg_d2 >= c2rg and c1gb2 + gb_d2 >= c2gb then
return true
else
return false
end
end
internal.color_deviation = function(compare_func, c1, c2, b1, g1, r1, b2, g2, r2)
local b1, g1, r1, b2, g2, r2 = internal.color_deviation_parse(b1, g1, r1, b2, g2, r2)
local c1b1, c1g1, c1r1 = ext.color_to_bgr(c1)
local c1b2 = c1b1
local c1g2 = c1g1
local c1r2 = c1r1
local c2b, c2g, c2r = ext.color_to_bgr(c2)
--log(c1b1, c1g1, c1r1, c1b2, c1g2, c1r2, c2b, c2g, c2r, b1, g1, r1, b2, g2, r2)
return compare_func(c1b1, c1g1, c1r1, c1b2, c1g2, c1r2, c2b, c2g, c2r, b1, g1, r1, b2, g2, r2)
end
--[==[ color_deviation_a
-- Возвращает true, если результат
-- входит в допустимое отклонение цвета,
-- иначе вернет false.
-- Все цвета задаются в формате bgr, не rgb.
-- Пилот так же предоставляет цвета в формате bgr.
-- b, g, r в любом варианте могут быть заданы таблицей.
-- Допустимый синтаксис:
-- <цвет1>, <цвет2>, <value>
-- Значения допустимого отклонения
-- ситаются допустимыми +/- b, g, r.
-- <цвет1>, <цвет2>, <b, g, r>
-- Значения допустимого отклонения
-- ситаются допустимыми +/- b, g, r.
-- <цвет>, <цвет2>, <b1, g1, r1>, <b2[, g2[, r2]]>
-- Значения b1, g1, r1 считаются допустимыми в плюс.
-- Значения b2, g2, r2 считаются допустимыми в минус.
-- Минус не пишется.]==]
ext.color_deviation_a = function(c1, c2, b1, g1, r1, b2, g2, r2)
return internal.color_deviation(internal.color_deviation_a, c1, c2, b1, g1, r1, b2, g2, r2)
end
--[==[ color_deviation_r
-- Возвращает true, если результат
-- входит в допустимое отклонение цвета,
-- иначе вернет false.
-- Все цвета задаются в формате bgr, не rgb.
-- Пилот так же предоставляет цвета в формате bgr.
-- b, g, r в любом варианте могут быть заданы таблицей.
-- Погрешность задется в
-- ПРОЦЕНТАХ от текущего значения канала,
-- с округлением в бОльшую сторону.
-- Например при цвете точки: 50 101 200 и погрешности
-- равной 10% допустимая погрешность составит:
-- 50*10%=5, 101*10%=10.1=11, 200*10%=20
-- 50 101 200 исходный цвет
-- 45 90 180 минимально допустимый
-- 55 112 220 максимально допустимый
-- Допустимый синтаксис:
-- <цвет1>, <цвет2>, <value>
-- Значения допустимого отклонения
-- ситаются допустимыми +/- b, g, r.
-- <цвет1>, <цвет2>, <b, g, r>
-- Значения допустимого отклонения
-- ситаются допустимыми +/- b, g, r.
-- <цвет>, <цвет2>, <b1, g1, r1>, <b2[, g2[, r2]]>
-- Значения b1, g1, r1 считаются допустимыми в плюс.
-- Значения b2, g2, r2 считаются допустимыми в минус.
-- Минус не пишется.]==]
ext.color_deviation_r = function(c1, c2, b1, g1, r1, b2, g2, r2)
return internal.color_deviation(internal.color_deviation_r, c1, c2, b1, g1, r1, b2, g2, r2)
end
--[==[ color_deviation_s
-- Возвращает true, если результат
-- входит в допустимое отклонение цвета,
-- иначе вернет false.
-- Все цвета задаются в формате bgr, не rgb.
-- Пилот так же предоставляет цвета в формате bgr.
-- b, g, r в любом варианте могут быть заданы таблицей.
-- Погрешность задется в
-- ПРОЦЕНТАХ от ОТНОШЕНИЯ каналов друг к другу,
-- с округлением в бОльшую сторону.
-- Например при цвете точки: 50 101 200 и погрешности
-- равной 10% допустимая погрешность составит:
-- 50*10%=5, 101*10%=10.1=11, 200*10%=20
-- 50 101 200 исходный цвет
-- 45 90 180 минимально допустимый
-- 55 112 220 максимально допустимый
-- Допустимый синтаксис:
-- <цвет1>, <цвет2>, <value>
-- Значения допустимого отклонения
-- ситаются допустимыми +/- br, rg, gb.
-- <цвет1>, <цвет2>, <br, rg, gb>
-- Значения допустимого отклонения
-- ситаются допустимыми +/- br, rg, gb.
-- <цвет>, <цвет2>, <br1, rg1, gb1>, <br2[, rg2[, gb2]]>
-- Значения br1, rg1, gb1 считаются допустимыми в плюс.
-- Значения br2, rg2, gb2 считаются допустимыми в минус.
-- Минус не пишется.]==]
ext.color_deviation_s = function(c1, c2, br1, rg1, gb1, br2, rg2, bg2)
return internal.color_deviation(internal.color_deviation_s, c1, c2, br1, rg1, gb1, br2, rg2, bg2)
end
internal.parse_channel_to_min_max = function(v)
local min, max
if v then
min, max = string.match (v, "([0-9x]+)-*([0-9x]*)")
min = tonumber(min)
max = tonumber(max)
if not max then max = min end
else
min, max = 0, 255
end
return min, max
end
internal.parse_split_color_to_min_max_bgr = function(c)
c = type(c) == "table" and c or {c}
if c.r or c.g or c.b then
c = {c}
end
local cc = ffi.new("uint8_t["..#c.."][6]")
--log(type(c,#c))
for i = 1, #c do
if type(c[i]) == "table" then
cc[i][0],cc[i][3] = internal.parse_channel_to_min_max(c[i].b)
cc[i][1],cc[i][4] = internal.parse_channel_to_min_max(c[i].g)
cc[i][2],cc[i][5] = internal.parse_channel_to_min_max(c[i].r)
else
local c1, c2 = string.match (c[i], "([0-9x]+)-*([0-9x]*)")
c1 = tonumber(c1)
c2 = tonumber(c2)
cc[i][0] = math.floor(c1/65536)
cc[i][1] = math.floor(c1/256-cc[i][0]*256)
cc[i][2] = c1-cc[i][0]*256*256-cc[i][1]*256
if c2 then
cc[i][3] = math.floor(c2/65536)
cc[i][4] = math.floor(c2/256-cc[i][3]*256)
cc[i][5] = c2-cc[i][3]*256*256-cc[i][4]*256
else
cc[i][3],cc[i][4],cc[i][5] = cc[i][0],cc[i][1],cc[i][2]
end
end
end
return cc
end
internal.findcolor_deviation_parse = function(v)
if type(v) == "number" then
if v > 0 then
v = {v, v, v, v, v, v}
else
v = nil -- вырубаем обработку отклонений.
end
elseif type(v) == "table" then
vv[i][0],vv[i][3] = internal.parse_channel_to_min_max(c[i].b)
vv[i][1],vv[i][4] = internal.parse_channel_to_min_max(c[i].g)
vv[i][2],vv[i][5] = internal.parse_channel_to_min_max(c[i].r)
end
return v[1], v[2], v[3], v[4], v[5], v[6]
end
--[====[ findcolor
-- Функция поиска цвета либо нескольких цветов,
-- с возможностью задать некоторые отклонения в оттенке.
-- Синтаксис:
-- result = findcolor(<x_start, y_start, x_end, y_end | table_crds>,
-- <color> [,method [,count [,deviaton [,deviation_type [,abs_flag]]]])
--
-- <x_start, y_start, x_end, y_end | table_crds>
-- Координтаы задаются в виде прямоугольной области
-- с указанием координаты левого верхнего угла
-- и правого нижнего угла.
-- Координаты могут быть заданы четырмя переменными:
-- x_start, y_start, x_end, y_end
-- либо массивом с аналогичной структурой данных:
-- {x_start, y_start, x_end, y_end}
-- Отсчет координат начинатся с 0, а не 1.
-- Т.е. для FullHD область поиска будет
-- 0, 0, 1919, 1079.
--
-- <color>
-- Цвета, которые непосредственно ищются.
-- Синтаксис списка цветов:
-- <color | {color_1 [,color_2 [,... [,color_N]]]}>
-- Допустимые форматы цвета:
-- < dec_hex_color | dec_hex_color_1-dec_hex_color_2 |
-- {[r=val_1] [,g=val_2] [,b=val_3]} | [{r="val_1-val_2"] [,g="val_3-val_4"] [,b="val_5-val_6"}] >
-- Форматы цветов можно кобинировать в рамках списка. Например:
-- 133972, 0x5060DD-0x5170DD, {r=10, g=0xFF, b=12-18}
--
-- [method]
-- Метод поиска. Значение по умолчанию: 2
-- 0/не задан - Быстрый метод. Получить изображение всего экрана.
-- 1 - устаревший метод, используется для совместимости. Очень медленный.
-- Для получения изображения всего экрана, а не окна используйте abs_flag.
-- 2 - надежный метод. Средняя скорость.
-- Для получения изображения всего экрана, а не окна используйте abs_flag.
-- хендла_окна - очень быстрый метод. Работает с перекрытыми окнами.
-- Предпочтительно использовать именно его. Не работает с некоторыми приложениями.
-- Для корректной работы может потребоваться задать хендл родительского окна.
-- адрес_картинки - Адрес изображения в формате bmp 24 бита.
-- "my_image.bmp" - изображение рядом с exe пилота.
-- "folder\\my_image.bmp" - изображение в папке folder рядом с exe пилота
-- "\\my_image.bmp" - изображение в корне диска, на котором лежит пилот.
-- [[d:\uopilot\images\my_image.bmp]] - абсолютный путь.
-- Учтите, что при задании адресов в lua символ '\' необходимо удваивать,
-- либо заменять на '/', либо брать весь адрес в двойные квадртные скобки.
-- адрес_памяти, - Поиск в ранее полученном изображении по средством функции getimage()
-- высота_изобр, Указывается адрес битовой маски, высота изображения, ширина и количество
-- ширина_изобр, байт на каждую строку. Из-за выравнивания размер строки может быть
-- длина. не кратным битности изображения. Данный параметр так же используется
-- для определения формата битовой маски (24 бита либо 24 бита цвет + 8 резерв).
--
-- [count]
-- Количество искомых изображений. 0 | -1 - найти все.
--
-- [deviation]
-- Допустимые отклонения цвета.
-- Синтаксис:
-- deviation_general | {blue, green, red} |
-- {blue_bottom, green_bottom, red_bottom, blue_upper, green_upper, red_upper}
-- Отклонения цвета может быть задано одним числом на все каналы в + и в -,
-- либо на каждый канал отдельно,
-- либо на каждый канал отдельно и отдельно нижняя и верхняя граница канала.
--
-- [deviation_type]
-- Тип расчета допустимого отклонения цвета. Значение по умолчанию "r".
-- Возможные значения:
-- "a" - absolute. Абсолютное отклонение канала.
-- Например, при цвете 50 100 200 и абсолютном отклонении 10,
-- допустимый диапазон цветов будет равен 40-60, 90-110, 190-210
-- "r" - relative. Относительное отклонение, задается в процентах.
-- Например, при цвете 50 100 200 и относительном отклонении 10,
-- допустимый диапазон цветов будет равен 45-55 90-110 180-220.
-- Округление происход в сторону расширения диапазона.
-- Например, при значении канала 101 и допустимом отклонении 10%,
-- допустимыми значениями канала будут 101-11=90 101+11=112, т.е. 90-112.
-- "s" - shadow. Затемнение/осветление. Рассчитывается соотношение каналов, задается в процентах.
-- Данный метод может быть полезен, например, при смене суток в игре.
-- В рамках данного метода цвет 50 100 200 и цвет 25 50 100 - будут полностью идентичны.
-- Для указанных цветов: 200/50=4 50/100=0.5 100/200=0.5
-- 100/25=4 25/50=0.5 50/100=0.5
-- При допустимом отклонении в 10, будут считаться допустимыми соотношения каналов:
-- 3.6-4.4 0.45-0.55 0.45-0.55
--
-- [abs_flag]
-- Флаг указывающий на то, что изображение должно быть получено не относительно с окна
-- к которому произведена привязка пилота через Ctrl+A или workwindow,
-- а относительно левого верхнего угла экрана.
-- Актуально для method 1, 2.]====]
ext.findcolor = function(x1, y1, x2, y2, c, method, count, deviation, deviation_type, abs_crds)
local t = os.clock()
if type(x1) == "table" then
abs_crds = count
deviation_type = method
deviation = c
count = y2
method = x2
c = y1
end
--log(1, os.clock() - t)
c = type(c) == "table" and c or {c}
method = method or workwindow()
deviation = internal.findcolor_deviation_parse(deviation)
deviation_type = deviation_type or "r"
--log(2, os.clock() - t)
local compare_func
if deviation_type == "r" then
compare_func = internal.color_deviation_r
elseif deviation_type == "a" then
compare_func = internal.color_deviation_a
elseif deviation_type == "s" then
compare_func = internal.color_deviation_s
end
--log(3, os.clock() - t)
local offset_x1, offset_y1, offset_y1, offset_y2 = 0, 0, 0, 0
local a, w, h, l
if type(method) == "table" then
a, w, h, l = method[1], method[2], method[3], method[4]
elseif type(method) == "number" then
a, w, h, l = getimage (x1, y1, x2, y2, method, abs_crds) -- getimage игнорирует x2, y2
offset_x2 = w - math.min(x2+1, w) -- getimage игнорирует x2, y2
offset_y2 = h - math.min(y2+1, h) -- getimage игнорирует x2, y2
saveimage(a,"image\\check.bmp")
elseif type(method) == "string" then
a, w, h, l = loadimage (method)
offset_x1 = math.min(x1, w)
offset_y1 = math.min(y1, h)
offset_x2 = w - math.min(x2+1, w)
offset_y2 = h - math.min(y2+1, h)
end
--log(4, os.clock() - t)
if not a then
log("capture failed")
stop_script()
end
log(a, w, h, l)
local cc = internal.parse_split_color_to_min_max_bgr(c)
local d = ffi.new("uint8_t[6]")
d[0], d[1], d[2], d[3], d[4], d[5] = internal.findcolor_deviation_parse(deviation, d)
local t = os.clock()
log(a + offset_y1*l, a+(h-offset_y2)*l-1, l)
local r = {}
if deviation then
for i = a + offset_y1*l, a+(h-offset_y2)*l-1, l do
local y = i
--p = zp + pa[0] + i / 3
--log(222, tostring(p))
--stop_script()
for i = i+offset_x1*3, i+l-offset_x2*3-1, 3 do
for j = 1, #c do
--log(cc[j][0], cc[j][1], cc[j][2], cc[j][3], cc[j][4], cc[j][5], rmem("unsigned char*",i)[0],rmem("unsigned char*",i+1)[0],rmem("unsigned char*",i+2)[0], d[0], d[1], d[2], d[3], d[4], d[5])
--if cc[j][0] - d[0] <= rmem("unsigned char*",i)[0] and cc[j][1] - d[1] <= rmem("unsigned char*",i)[1] and cc[j][2] - d[2] <= rmem("unsigned char*",i)[2] and
-- cc[j][3] + d[3] >= rmem("unsigned char*",i)[0] and cc[j][4] + d[4] >= rmem("unsigned char*",i)[1] and cc[j][5] + d[5] >= rmem("unsigned char*",i)[2] then
--log((i-y)/3 + 1, (y-a)/l/3 + 1)
if compare_func(cc[j][0], cc[j][1], cc[j][2], cc[j][3], cc[j][4], cc[j][5], rmem("unsigned char*",i)[0],rmem("unsigned char*",i)[1],rmem("unsigned char*",i)[2], d[0], d[1], d[2], d[3], d[4], d[5]) then
r[#r+1] = {}
r[#r][1] = (i-y)/3
r[#r][2] = math.floor((y-a)/l)
r[#r][3] = cc[j][1]*256*256 + cc[j][2]*256 + cc[j][3]
r[#r][4] = cc[j][4]*256*256 + cc[j][5]*256 + cc[j][6]
--log(r[#r][1],r[#r][2])
if count == #r then
return r
end
end
end
--p = p + 1
end
end
else
for y = 1, w do
for x = 1, h do
for i = 1, #deviation do
if deviation_func() then
end
end
end
end
end
--[[
local pa = ffi.new("unsigned int[1]",a)
--local zp = ffi.new("unsigned char *")
local p = ffi.new("unsigned char[3]")
local p = ffi.new("unsigned char *")
p = p+pa[0]
--log(a)
--log(222, tostring(p))
--stop_script()
--log(333, #c)
--log(7, os.clock() - t)
--ext.lg(d)
--end_script()
--log(333, #c)
--log(8, os.clock() - t)
local t = os.clock()
--log(l)
local r = {}
if deviation then
for i = 0, h*l-1, l do
local y = i
--p = zp + pa[0] + i / 3
--log(222, tostring(p))
--stop_script()
for i = i, i+w*3-1, 3 do
for j = 1, #c do
--log(i)
--log(cc[j][0], cc[j][1], cc[j][2], cc[j][3], cc[j][4], cc[j][5], p[0], p[1], p[2], d[1], d[2], d[3], d[4], d[5], d[6])
--if compare_func(cc[j][0], cc[j][1], cc[j][2], cc[j][3], cc[j][4], cc[j][5], p[0], p[1], p[2], d[1], d[2], d[3], d[4], d[5], d[6]) then
--log(cc[j][0], cc[j][1], cc[j][2], cc[j][3], cc[j][4], cc[j][5], p[i], p[i+1], p[i+2], d[1], d[2], d[3], d[4], d[5], d[6])
if compare_func(cc[j][0], cc[j][1], cc[j][2], cc[j][3], cc[j][4], cc[j][5], p[i], p[i+1], p[i+2], d[1], d[2], d[3], d[4], d[5], d[6]) then
r[#r+1] = {}
r[#r][1] = (i-y)/3 + 1
r[#r][2] = (y)/l + 1
r[#r][3] = cc[j][1]*256*256 + cc[j][2]*256 + cc[j][3]
r[#r][4] = cc[j][4]*256*256 + cc[j][5]*256 + cc[j][6]
--log(r[#r][1],r[#r][2])
end
end
--p = p + 1
end
end
else
for y = 1, w do
for x = 1, h do
for i = 1, #deviation do
if deviation_func() then
end
end
end
end
end
]]
deleteimage = internal.deleteimage
speed = speed + os.clock() - t
catch = #r
return r
end
return ext