ms-vite-plugin 1.4.55 → 1.4.57
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/docs/AGENTS.md +2 -0
- package/docs/SKILL.md +3 -0
- package/docs/api/image.md +21 -1
- package/docs/apicn/image.md +21 -1
- package/docs/apilua/image.md +20 -1
- package/docs/apilua/node.md +84 -22
- package/docs/apilua/opencv.md +16 -13
- package/docs/apipython/image.md +19 -1
- package/package.json +1 -1
package/docs/AGENTS.md
CHANGED
|
@@ -12,6 +12,8 @@
|
|
|
12
12
|
- Python 项目使用 Python 文档与写法。
|
|
13
13
|
- Lua 项目使用 Lua 文档与写法。
|
|
14
14
|
- 不要混用 JavaScript、Python 与 Lua API。
|
|
15
|
+
- Lua 只提供英文方法,没有中文别名。
|
|
16
|
+
- Lua 模块通过 `require("device")` 加载;`Sleep`、`StartThread` 等是裸全局。
|
|
15
17
|
- 不要把快点JS Python 脚本当成普通 CPython 脚本。
|
|
16
18
|
- 不要对快点JS Python 脚本运行 `python -m py_compile`、`py_compile` 或类似 CPython 编译校验。
|
|
17
19
|
- 不要创建、保留或同步 `__pycache__`、`.pyc` 作为项目改动。
|
package/docs/SKILL.md
CHANGED
|
@@ -19,6 +19,9 @@ description: 快点JS专用开发助手。用于快点JS项目开发、本地 AP
|
|
|
19
19
|
- JavaScript 项目使用 JavaScript 文档与写法。
|
|
20
20
|
- Lua 项目使用 Lua 文档与写法。
|
|
21
21
|
- 不要混用 JavaScript、Python 与 Lua API。
|
|
22
|
+
- Lua 只提供英文方法,没有中文别名。
|
|
23
|
+
- Lua 模块通过 `require("device")` 加载;`Sleep`、`StartThread` 等是裸全局。
|
|
24
|
+
- Lua 用户模块请用 `require("foo")` / `require("lib.bar")`。Release 打包默认会把 `scripts` 下除 `main.lua` 外的用户 `.lua` 合并进单个 `main.lua`;不要用 `dofile` / `loadfile` 按路径加载这些文件。
|
|
22
25
|
- 文档未确认的能力必须明确说明无法确认,并给出保守方案。
|
|
23
26
|
- 快点JS Python 脚本不使用 CPython 编译校验;不要运行 `python -m py_compile`、`py_compile` 或类似命令。
|
|
24
27
|
|
package/docs/api/image.md
CHANGED
|
@@ -504,6 +504,7 @@ function findImage(
|
|
|
504
504
|
rgb?: boolean,
|
|
505
505
|
options?: {
|
|
506
506
|
scaleFactors?: number[];
|
|
507
|
+
orz?: number;
|
|
507
508
|
},
|
|
508
509
|
): {
|
|
509
510
|
index: number; // 模板图片索引,从 0 开始
|
|
@@ -533,8 +534,9 @@ function findImage(
|
|
|
533
534
|
| `limit` | number | 是 | - | 最大查找数量,每个模板图片最多找 limit 个匹配结果 |
|
|
534
535
|
| `method` | number | 是 | - | 匹配方法,见下方说明 |
|
|
535
536
|
| `rgb` | boolean | 否 | `false` | 是否使用 RGB 找图,默认 `false` 会自动转灰度找图 |
|
|
536
|
-
| `options` | object | 否 | - |
|
|
537
|
+
| `options` | object | 否 | - | 额外选项。`scaleFactors` 仅 method=`99` 生效;`orz` 用于按方向取结果 |
|
|
537
538
|
| `options.scaleFactors` | number\[] | 否 | `[1.0, 0.9, 1.1, 0.8, 1.2]` | 仅 method=`99` 生效。模板相对当前图的缩放比列表(**不是** `device.getScreenScale()`)。应按 baseScale 动态计算,见下方详解;默认值只适合尺寸接近时的盲扫 |
|
|
539
|
+
| `options.orz` | number | 否 | 不传 | 查找方向(1-8),与找色 `orz` 相同。不传或非 1-8 时仍按相似度从高到低返回。传入 1-8 时按该方向取前 `limit` 个达标结果;`limit=1` 时只返回该方向第一个,不会把其余命中都找出来。method `0`(SIFT)会先完成匹配再按方向排序截取 |
|
|
538
540
|
|
|
539
541
|
#### method 匹配方法说明
|
|
540
542
|
|
|
@@ -744,6 +746,24 @@ if (matches.length > 0) {
|
|
|
744
746
|
action.click(best.centerX, best.centerY, 100, false);
|
|
745
747
|
}
|
|
746
748
|
|
|
749
|
+
// 只要右下角那一个(界面上可能有很多份,不必全找出来)
|
|
750
|
+
const corner = image.findImage(
|
|
751
|
+
"screen",
|
|
752
|
+
"btn.png",
|
|
753
|
+
0,
|
|
754
|
+
0,
|
|
755
|
+
0,
|
|
756
|
+
0,
|
|
757
|
+
0.9,
|
|
758
|
+
1,
|
|
759
|
+
5,
|
|
760
|
+
false,
|
|
761
|
+
{ orz: 5 }, // 与找色相同:5 右下角起,纵向开始
|
|
762
|
+
);
|
|
763
|
+
if (corner.length > 0) {
|
|
764
|
+
action.click(corner[0].centerX, corner[0].centerY, 100, false);
|
|
765
|
+
}
|
|
766
|
+
|
|
747
767
|
// 2) 缩放全分辨率找图:按「截模板设备宽 / 当前设备宽」计算比例
|
|
748
768
|
// 假设模板是在宽度 750 的设备上截的
|
|
749
769
|
const templateDeviceWidth = 750;
|
package/docs/apicn/image.md
CHANGED
|
@@ -511,6 +511,7 @@ function 找图(
|
|
|
511
511
|
是否使用RGB找图?: 布尔值,
|
|
512
512
|
选项?: {
|
|
513
513
|
scaleFactors?: 数字[];
|
|
514
|
+
orz?: 数字;
|
|
514
515
|
},
|
|
515
516
|
): {
|
|
516
517
|
index: 数字; // 模板图片索引,从 0 开始
|
|
@@ -542,8 +543,9 @@ function 找图(
|
|
|
542
543
|
| `限制数量` | 数字 | 是 | - | 最大查找数量,每个模板图片最多找 限制数量 个匹配结果 |
|
|
543
544
|
| `方法` | 数字 | 是 | - | 匹配方法,见下方说明 |
|
|
544
545
|
| `是否使用RGB找图` | 布尔值 | 否 | `false` | 是否使用 RGB 找图,默认 `false` 会自动转灰度找图 |
|
|
545
|
-
| `选项` | 对象 | 否 | - |
|
|
546
|
+
| `选项` | 对象 | 否 | - | 额外选项。`scaleFactors` 仅 方法=`99` 生效;`orz` 用于按方向取结果 |
|
|
546
547
|
| `选项.scaleFactors` | 数字\[] | 否 | `[1.0, 0.9, 1.1, 0.8, 1.2]` | 仅 方法=`99` 生效。模板相对当前图的缩放比列表(**不是** `$设备.获取屏幕缩放比例()`)。应按 baseScale 动态计算,见下方详解;默认值只适合尺寸接近时的盲扫 |
|
|
548
|
+
| `选项.orz` | 数字 | 否 | 不传 | 查找方向(1-8),与单点找色的查找方向相同。不传或非 1-8 时仍按相似度从高到低返回。传入 1-8 时按该方向取前 `限制数量` 个达标结果;`限制数量=1` 时只返回该方向第一个,不会把其余命中都找出来。方法 `0`(SIFT)会先完成匹配再按方向排序截取 |
|
|
547
549
|
|
|
548
550
|
#### 方法(method)匹配说明
|
|
549
551
|
|
|
@@ -753,6 +755,24 @@ if (匹配区域数组.length > 0) {
|
|
|
753
755
|
$动作.点击(best.centerX, best.centerY, 100, false);
|
|
754
756
|
}
|
|
755
757
|
|
|
758
|
+
// 只要右下角那一个(界面上可能有很多份,不必全找出来)
|
|
759
|
+
const 右下角 = $图片.找图(
|
|
760
|
+
"screen",
|
|
761
|
+
"btn.png",
|
|
762
|
+
0,
|
|
763
|
+
0,
|
|
764
|
+
0,
|
|
765
|
+
0,
|
|
766
|
+
0.9,
|
|
767
|
+
1,
|
|
768
|
+
5,
|
|
769
|
+
false,
|
|
770
|
+
{ orz: 5 }, // 与单点找色相同:5 右下角起,纵向开始
|
|
771
|
+
);
|
|
772
|
+
if (右下角.length > 0) {
|
|
773
|
+
$动作.点击(右下角[0].centerX, 右下角[0].centerY, 100, false);
|
|
774
|
+
}
|
|
775
|
+
|
|
756
776
|
// 2) 缩放全分辨率找图:按「截模板设备宽 / 当前设备宽」计算比例
|
|
757
777
|
// 假设模板是在宽度 750 的设备上截的
|
|
758
778
|
const 模板设备宽 = 750;
|
package/docs/apilua/image.md
CHANGED
|
@@ -614,8 +614,9 @@ function findImage(imageId, templateImageId, x, y, ex, ey, threshold, limit, met
|
|
|
614
614
|
| `limit` | number | 是 | - | 最大查找数量,每个模板图片最多找 limit 个匹配结果 |
|
|
615
615
|
| `method` | number | 是 | - | 匹配方法,见下方说明 |
|
|
616
616
|
| `rgb` | boolean | 否 | `false` | 是否使用 RGB 找图,默认 `false` 会自动转灰度找图 |
|
|
617
|
-
| `options` | table | 否 | - |
|
|
617
|
+
| `options` | table | 否 | - | 额外选项。`scaleFactors` 仅 method=`99` 生效;`orz` 用于按方向取结果 |
|
|
618
618
|
| `options.scaleFactors` | number\[] | 否 | `[1.0, 0.9, 1.1, 0.8, 1.2]` | 仅 method=`99` 生效。模板相对当前图的缩放比列表(**不是** `device.getScreenScale()`)。应按 baseScale 动态计算,见下方详解;默认值只适合尺寸接近时的盲扫 |
|
|
619
|
+
| `options.orz` | number | 否 | 不传 | 查找方向(1-8),与找色 `orz` 相同。不传或非 1-8 时仍按相似度从高到低返回。传入 1-8 时按该方向取前 `limit` 个达标结果;`limit=1` 时只返回该方向第一个,不会把其余命中都找出来。method `0`(SIFT)会先完成匹配再按方向排序截取 |
|
|
619
620
|
|
|
620
621
|
#### method 匹配方法说明
|
|
621
622
|
|
|
@@ -824,6 +825,24 @@ if #matches > 0 then
|
|
|
824
825
|
print("找到匹配,置信度: " .. tostring(best.confidence))
|
|
825
826
|
action.click(best.centerX, best.centerY, 100, false)
|
|
826
827
|
end
|
|
828
|
+
|
|
829
|
+
-- 只要右下角那一个(界面上可能有很多份,不必全找出来)
|
|
830
|
+
local corner = image.findImage(
|
|
831
|
+
"screen",
|
|
832
|
+
"btn.png",
|
|
833
|
+
0,
|
|
834
|
+
0,
|
|
835
|
+
0,
|
|
836
|
+
0,
|
|
837
|
+
0.9,
|
|
838
|
+
1,
|
|
839
|
+
5,
|
|
840
|
+
false,
|
|
841
|
+
{ orz = 5 } -- 与找色相同:5 右下角起,纵向开始
|
|
842
|
+
)
|
|
843
|
+
if #corner > 0 then
|
|
844
|
+
action.click(corner[1].centerX, corner[1].centerY, 100, false)
|
|
845
|
+
end
|
|
827
846
|
-- 2) 缩放全分辨率找图:按「截模板设备宽 / 当前设备宽」计算比例
|
|
828
847
|
-- 假设模板是在宽度 750 的设备上截的
|
|
829
848
|
local templateDeviceWidth = 750
|
package/docs/apilua/node.md
CHANGED
|
@@ -58,11 +58,12 @@ local listPage = node.createNodeSelector({ mode = 2 })
|
|
|
58
58
|
|
|
59
59
|
| 字段 | 说明 |
|
|
60
60
|
| --- | --- |
|
|
61
|
-
| `id` | 节点 ID
|
|
61
|
+
| `id` | 节点 ID,不要改 |
|
|
62
62
|
| `identifier` | 控件标识符 |
|
|
63
63
|
| `label` | 标签文案 |
|
|
64
64
|
| `type` | 类型,如 `XCUIElementTypeButton` |
|
|
65
65
|
| `value` | 当前值 |
|
|
66
|
+
| `placeholderValue` | 输入框占位文字 |
|
|
66
67
|
| `title` | 标题 |
|
|
67
68
|
| `enabled` | 是否启用 |
|
|
68
69
|
| `visible` | 是否可见 |
|
|
@@ -76,8 +77,16 @@ local listPage = node.createNodeSelector({ mode = 2 })
|
|
|
76
77
|
|
|
77
78
|
| 方法 | 说明 |
|
|
78
79
|
| --- | --- |
|
|
80
|
+
| `hittable()` | 当前是否可点击(可见且未被挡住) |
|
|
81
|
+
| `scrollToVisible()` | 仅滚动到可见,不点击;一般不必手动调用 |
|
|
82
|
+
| `tap()` | 单击;不可见时会先自动滚到可见 |
|
|
83
|
+
| `doubleTap()` | 双击;不可见时会先自动滚到可见 |
|
|
84
|
+
| `press(duration?)` | 长按,`duration` 单位毫秒,默认 500;不可见时会先自动滚到可见 |
|
|
79
85
|
| `clickCenter()` | 点击中心坐标(坐标点击,不会自动滚动) |
|
|
80
86
|
| `clickRandom()` | 在节点范围内随机点击(坐标点击,不会自动滚动) |
|
|
87
|
+
| `clearInput()` | 清空输入;不可见时会先自动滚到可见 |
|
|
88
|
+
| `input(text)` | 追加输入,不清空原内容;不可见时会先自动滚到可见 |
|
|
89
|
+
| `setValue(text)` | 设置值(见下方;不可见时会先自动滚到可见) |
|
|
81
90
|
| `parent()` | 父节点 |
|
|
82
91
|
| `child(index)` | 第 `index` 个子节点 |
|
|
83
92
|
| `allChildren()` | 全部子节点 |
|
|
@@ -93,7 +102,7 @@ local listPage = node.createNodeSelector({ mode = 2 })
|
|
|
93
102
|
|
|
94
103
|
| 方法 | 说明 |
|
|
95
104
|
| --- | --- |
|
|
96
|
-
| `releaseNode()` | 立刻释放选择器;与 `<close>`
|
|
105
|
+
| `releaseNode()` | 立刻释放选择器;与 `<close>` 二选一即可 |
|
|
97
106
|
| `loadNode(timeout?)` | 重新加载界面节点,默认超时 5000ms |
|
|
98
107
|
| `clearSelector()` | 清除已设置的筛选条件 |
|
|
99
108
|
| `xml(timeout?)` | 获取界面 XML,失败返回 `nil` |
|
|
@@ -115,7 +124,7 @@ selector:releaseNode() -- 手动释放
|
|
|
115
124
|
|
|
116
125
|
### 筛选条件
|
|
117
126
|
|
|
118
|
-
可链式调用,多个条件同时满足(并且关系)。
|
|
127
|
+
可链式调用,多个条件同时满足(并且关系)。
|
|
119
128
|
带 `Match` 的为模糊/正则匹配。
|
|
120
129
|
|
|
121
130
|
**文本**
|
|
@@ -126,6 +135,7 @@ selector:releaseNode() -- 手动释放
|
|
|
126
135
|
| `title` / `titleMatch` | 标题 |
|
|
127
136
|
| `identifier` / `identifierMatch` | 标识符 |
|
|
128
137
|
| `value` / `valueMatch` | 值 |
|
|
138
|
+
| `placeholderValue` / `placeholderValueMatch` | 占位文字 |
|
|
129
139
|
|
|
130
140
|
**类型与状态**
|
|
131
141
|
|
|
@@ -152,6 +162,7 @@ selector:label("确定"):type("XCUIElementTypeButton"):getOneNodeInfo(3000)
|
|
|
152
162
|
-- 模糊
|
|
153
163
|
selector:labelMatch(".*登录.*"):getNodeInfo(3000)
|
|
154
164
|
selector:identifierMatch("^login_"):getNodeInfo(3000)
|
|
165
|
+
selector:placeholderValue("请输入账号"):getOneNodeInfo(3000)
|
|
155
166
|
-- 组合
|
|
156
167
|
selector
|
|
157
168
|
:type("XCUIElementTypeTextField")
|
|
@@ -165,25 +176,76 @@ selector
|
|
|
165
176
|
|
|
166
177
|
## 节点操作说明
|
|
167
178
|
|
|
179
|
+
### 是否可点 / 滚到可见
|
|
180
|
+
|
|
181
|
+
`tap` / `doubleTap` / `press` / `setValue` / `clearInput` / `input` 在元素当前不可见时,会**自动**先滚到可见再操作,一般不用手写滚动:
|
|
182
|
+
|
|
183
|
+
```lua
|
|
184
|
+
-- 推荐:直接操作,不可见时会自动滚到可见
|
|
185
|
+
btn:tap()
|
|
186
|
+
btn:doubleTap()
|
|
187
|
+
btn:press(800)
|
|
188
|
+
btn:setValue("hello")
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
- `hittable()`:当前能否点到(可见且未被挡住),用于排查“点了没反应”
|
|
192
|
+
- `scrollToVisible()`:只滚到可见、不点击;仅在你想先露出元素、稍后再操作时使用
|
|
193
|
+
- `clickCenter()` / `clickRandom()`:按坐标点击,**不会**自动滚动
|
|
194
|
+
|
|
168
195
|
### 点击
|
|
169
196
|
|
|
170
197
|
| 方法 | 说明 |
|
|
171
198
|
| --- | --- |
|
|
199
|
+
| `tap()` | 推荐,单击;不可见时自动滚到可见 |
|
|
200
|
+
| `doubleTap()` | 双击;不可见时自动滚到可见 |
|
|
201
|
+
| `press(ms?)` | 长按,默认 500ms;不可见时自动滚到可见 |
|
|
172
202
|
| `clickCenter()` | 点中心坐标,不自动滚动 |
|
|
173
203
|
| `clickRandom()` | 范围内随机点,不自动滚动 |
|
|
174
204
|
|
|
175
|
-
输入请配合 `ime` 或 `action.input`。
|
|
176
|
-
|
|
177
205
|
```lua
|
|
178
206
|
local node = require("node")
|
|
179
207
|
local selector <close> = node.createNodeSelector()
|
|
180
208
|
local btn = selector:label("确定"):type("XCUIElementTypeButton"):getOneNodeInfo(3000)
|
|
181
209
|
|
|
182
210
|
if btn then
|
|
183
|
-
btn:
|
|
211
|
+
btn:tap()
|
|
212
|
+
btn:doubleTap()
|
|
213
|
+
btn:press(800)
|
|
184
214
|
end
|
|
185
215
|
```
|
|
186
216
|
|
|
217
|
+
### 输入与设值
|
|
218
|
+
|
|
219
|
+
| 方法 | 说明 |
|
|
220
|
+
| --- | --- |
|
|
221
|
+
| `clearInput()` | 清空;不可见时也会自动滚到可见 |
|
|
222
|
+
| `input(text)` | 追加输入,不清空原内容 |
|
|
223
|
+
| `setValue(text)` | 按控件类型设置;不可见时会先自动滚到可见 |
|
|
224
|
+
|
|
225
|
+
**`setValue` 行为**
|
|
226
|
+
|
|
227
|
+
| 控件类型 | 传参 | 效果 |
|
|
228
|
+
| --- | --- | --- |
|
|
229
|
+
| `PickerWheel` | 选项文案,如 `"1小时"` | 滚到该选项(控件本身不可见时也会先自动滚到可见) |
|
|
230
|
+
| 文本框类(TextField 等) | 字符串 | 聚焦后追加输入,不先清空 |
|
|
231
|
+
|
|
232
|
+
覆盖原内容请先清空:
|
|
233
|
+
|
|
234
|
+
```lua
|
|
235
|
+
field:clearInput()
|
|
236
|
+
field:setValue("hello")
|
|
237
|
+
-- 或
|
|
238
|
+
field:clearInput()
|
|
239
|
+
field:input("hello")
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
```lua
|
|
243
|
+
local wheel = selector:type("XCUIElementTypePickerWheel"):getOneNodeInfo(3000)
|
|
244
|
+
if wheel then
|
|
245
|
+
-- 不可见时会自动滚到可见,再调到目标选项
|
|
246
|
+
wheel:setValue("1小时")
|
|
247
|
+
end
|
|
248
|
+
```
|
|
187
249
|
|
|
188
250
|
### 树导航
|
|
189
251
|
|
|
@@ -191,10 +253,10 @@ end
|
|
|
191
253
|
local field = selector:type("XCUIElementTypeTextField"):getOneNodeInfo(3000)
|
|
192
254
|
if field then
|
|
193
255
|
local parent = field:parent()
|
|
194
|
-
local children = parent:allChildren()
|
|
256
|
+
local children = parent and parent:allChildren() or {}
|
|
195
257
|
local prev = field:previousSiblings()
|
|
196
258
|
local next = field:nextSiblings()
|
|
197
|
-
local second = parent:child(1)
|
|
259
|
+
local second = parent and parent:child(1)
|
|
198
260
|
end
|
|
199
261
|
```
|
|
200
262
|
|
|
@@ -206,14 +268,12 @@ end
|
|
|
206
268
|
|
|
207
269
|
```lua
|
|
208
270
|
local node = require("node")
|
|
209
|
-
local ime = require("ime")
|
|
210
271
|
local selector <close> = node.createNodeSelector()
|
|
211
272
|
|
|
212
273
|
local user = selector:type("XCUIElementTypeTextField"):getOneNodeInfo(5000)
|
|
213
274
|
if user then
|
|
214
|
-
user:
|
|
215
|
-
|
|
216
|
-
ime.input("demo_user")
|
|
275
|
+
user:clearInput()
|
|
276
|
+
user:setValue("demo_user")
|
|
217
277
|
end
|
|
218
278
|
|
|
219
279
|
local pass = selector
|
|
@@ -221,9 +281,8 @@ local pass = selector
|
|
|
221
281
|
:type("XCUIElementTypeSecureTextField")
|
|
222
282
|
:getOneNodeInfo(3000)
|
|
223
283
|
if pass then
|
|
224
|
-
pass:
|
|
225
|
-
|
|
226
|
-
ime.input("password")
|
|
284
|
+
pass:clearInput()
|
|
285
|
+
pass:setValue("password")
|
|
227
286
|
end
|
|
228
287
|
|
|
229
288
|
local login = selector
|
|
@@ -232,7 +291,7 @@ local login = selector
|
|
|
232
291
|
:type("XCUIElementTypeButton")
|
|
233
292
|
:getOneNodeInfo(3000)
|
|
234
293
|
if login then
|
|
235
|
-
login:
|
|
294
|
+
login:tap()
|
|
236
295
|
end
|
|
237
296
|
```
|
|
238
297
|
|
|
@@ -243,7 +302,7 @@ local node = require("node")
|
|
|
243
302
|
local selector <close> = node.createNodeSelector({ mode = 2 })
|
|
244
303
|
local item = selector:label("第 30 项"):getOneNodeInfo(5000)
|
|
245
304
|
if item then
|
|
246
|
-
item:
|
|
305
|
+
item:tap() -- 不在可见区域时会自动滚动
|
|
247
306
|
end
|
|
248
307
|
```
|
|
249
308
|
|
|
@@ -262,14 +321,17 @@ selector:releaseNode()
|
|
|
262
321
|
|
|
263
322
|
## 常见问题
|
|
264
323
|
|
|
265
|
-
**找不到节点**
|
|
324
|
+
**找不到节点**
|
|
266
325
|
加大超时;减少条件或改用 `*Match`;换 `mode`;用 `xml()` 看实际文案和类型。
|
|
267
326
|
|
|
268
|
-
**点了没反应**
|
|
269
|
-
|
|
327
|
+
**点了没反应**
|
|
328
|
+
先看 `hittable()`;确认点到的是目标控件;可对比 `clickCenter()`。
|
|
329
|
+
|
|
330
|
+
**输入叠在旧文字后面**
|
|
331
|
+
`input` / 文本类 `setValue` 是追加,先 `clearInput()`。
|
|
270
332
|
|
|
271
|
-
|
|
272
|
-
|
|
333
|
+
**滚轮设不中**
|
|
334
|
+
`setValue` 要传界面上显示的选项文案;确认类型是 `PickerWheel`;多列时选对那一列。
|
|
273
335
|
|
|
274
336
|
**要不要释放**
|
|
275
337
|
要。用 `<close>` 自动释放,或用完调 `releaseNode()`,两种都行。
|
package/docs/apilua/opencv.md
CHANGED
|
@@ -59,7 +59,7 @@ local gray = cv.cvtColor(src, { code = cv.COLOR_BGR2GRAY })
|
|
|
59
59
|
local edges = cv.Canny(gray, { threshold1 = 100, threshold2 = 200 })
|
|
60
60
|
local feat = cv.SIFT(gray, { nfeatures = 500 })
|
|
61
61
|
if feat then
|
|
62
|
-
|
|
62
|
+
print("keypoints=" .. tostring(#feat.keypoints))
|
|
63
63
|
cv.release(feat.descriptors)
|
|
64
64
|
end
|
|
65
65
|
cv.imwrite(file.getInternalDir("documents") .. "/edges.png", edges)
|
|
@@ -143,9 +143,11 @@ function imread(path) end
|
|
|
143
143
|
|
|
144
144
|
```lua
|
|
145
145
|
local cv = require("cv")
|
|
146
|
+
local file = require("file")
|
|
147
|
+
local image = require("image")
|
|
146
148
|
local a = cv.imread("template.png")
|
|
147
149
|
local dir = file.getInternalDir("documents")
|
|
148
|
-
local b = cv.imread(
|
|
150
|
+
local b = cv.imread(dir .. "/shot.jpg")
|
|
149
151
|
local imageId = image.captureFullScreen()
|
|
150
152
|
local c = cv.imread(imageId)
|
|
151
153
|
image.release(imageId)
|
|
@@ -205,8 +207,9 @@ function imwrite(path, mat) end
|
|
|
205
207
|
|
|
206
208
|
```lua
|
|
207
209
|
local cv = require("cv")
|
|
210
|
+
local file = require("file")
|
|
208
211
|
local src = cv.capture()
|
|
209
|
-
cv.imwrite(
|
|
212
|
+
cv.imwrite(file.getInternalDir("documents") .. "/out.png", src)
|
|
210
213
|
cv.release(src)
|
|
211
214
|
```
|
|
212
215
|
|
|
@@ -314,7 +317,7 @@ local cv = require("cv")
|
|
|
314
317
|
local a = cv.capture()
|
|
315
318
|
local b = cv.clone(a)
|
|
316
319
|
cv.release(a)
|
|
317
|
-
|
|
320
|
+
print(cv.isRelease(a)) -- true
|
|
318
321
|
cv.release(b)
|
|
319
322
|
```
|
|
320
323
|
|
|
@@ -556,17 +559,17 @@ local cv = require("cv")
|
|
|
556
559
|
cv.rectangle(src, {
|
|
557
560
|
pt1 = { x = 10, y = 10 },
|
|
558
561
|
pt2 = { x = 100, y = 80 },
|
|
559
|
-
color =
|
|
562
|
+
color = { 0, 0, 255 },
|
|
560
563
|
thickness = 2,
|
|
561
564
|
})
|
|
562
565
|
cv.circle(src, { center = { x = 50, y = 50 }, radius = 20, color = "#00FF00", thickness = -1 })
|
|
563
|
-
cv.line(src, { pt1 = { x = 0, y = 0 }, pt2 = { x = 100, y = 100 }, color =
|
|
566
|
+
cv.line(src, { pt1 = { x = 0, y = 0 }, pt2 = { x = 100, y = 100 }, color = { 255, 0, 0 }, thickness = 2 })
|
|
564
567
|
cv.putText(src, {
|
|
565
568
|
text = "hello",
|
|
566
569
|
org = { x = 20, y = 40 },
|
|
567
570
|
fontFace = cv.FONT_HERSHEY_SIMPLEX,
|
|
568
571
|
fontScale = 1,
|
|
569
|
-
color =
|
|
572
|
+
color = { 255, 255, 255 },
|
|
570
573
|
thickness = 2,
|
|
571
574
|
})
|
|
572
575
|
```
|
|
@@ -587,9 +590,9 @@ function fillPoly(mat, options) end
|
|
|
587
590
|
```lua
|
|
588
591
|
local cv = require("cv")
|
|
589
592
|
cv.polylines(src, {
|
|
590
|
-
pts =
|
|
593
|
+
pts = { { x = 0, y = 0 }, { x = 100, y = 0 }, { x = 100, y = 80 }, { x = 0, y = 80 } },
|
|
591
594
|
isClosed = true,
|
|
592
|
-
color =
|
|
595
|
+
color = { 0, 255, 0 },
|
|
593
596
|
thickness = 2,
|
|
594
597
|
})
|
|
595
598
|
```
|
|
@@ -621,11 +624,11 @@ function matchTemplate(image, templ, methodOrOptions) end
|
|
|
621
624
|
```lua
|
|
622
625
|
local cv = require("cv")
|
|
623
626
|
local loc = cv.matchTemplateLoc(src, templ, { method = cv.TM_CCOEFF_NORMED })
|
|
624
|
-
|
|
627
|
+
print(string.format("best=(%s,%s) max=%s", loc.x, loc.y, loc.maxVal))
|
|
625
628
|
cv.rectangle(src, {
|
|
626
629
|
pt1 = { x = loc.x, y = loc.y },
|
|
627
630
|
pt2 = { x = loc.x + tw, y = loc.y + th },
|
|
628
|
-
color =
|
|
631
|
+
color = { 0, 0, 255 },
|
|
629
632
|
thickness = 2,
|
|
630
633
|
})
|
|
631
634
|
```
|
|
@@ -653,8 +656,8 @@ function findContours(mat, options) end
|
|
|
653
656
|
|
|
654
657
|
```lua
|
|
655
658
|
local cv = require("cv")
|
|
656
|
-
local
|
|
657
|
-
|
|
659
|
+
local ret = cv.findContours(bin, { mode = cv.RETR_TREE, method = cv.CHAIN_APPROX_SIMPLE })
|
|
660
|
+
print("count=" .. tostring(#ret.contours))
|
|
658
661
|
```
|
|
659
662
|
|
|
660
663
|
### boundingRect / minAreaRect / contourArea / arcLength / approxPolyDP
|
package/docs/apipython/image.md
CHANGED
|
@@ -479,8 +479,9 @@ def findImage(id: str, templateImageId: str, x: int, y: int, ex: int, ey: int, t
|
|
|
479
479
|
| `limit` | int | 是 | <br /> | 最大查找数量,每个模板图片最多找 limit 个匹配结果 |
|
|
480
480
|
| `method` | int | 是 | <br /> | 匹配方法,见下方说明 |
|
|
481
481
|
| `rgb` | bool | 否 | `False` | 是否使用 RGB 找图,默认 `False` 会自动转灰度找图 |
|
|
482
|
-
| `options` | dict | 否 | `{}` |
|
|
482
|
+
| `options` | dict | 否 | `{}` | 额外选项。`scaleFactors` 仅 method=`99` 生效;`orz` 用于按方向取结果 |
|
|
483
483
|
| `options.scaleFactors` | list\[float] | 否 | `[1.0, 0.9, 1.1, 0.8, 1.2]` | 仅 method=`99` 生效。模板相对当前图的缩放比列表(**不是** `device.getScreenScale()`)。应按 baseScale 动态计算,见下方详解;默认值只适合尺寸接近时的盲扫 |
|
|
484
|
+
| `options.orz` | int | 否 | 不传 | 查找方向(1-8),与找色 `orz` 相同。不传或非 1-8 时仍按相似度从高到低返回。传入 1-8 时按该方向取前 `limit` 个达标结果;`limit=1` 时只返回该方向第一个,不会把其余命中都找出来。method `0`(SIFT)会先完成匹配再按方向排序截取 |
|
|
484
485
|
|
|
485
486
|
#### method 匹配方法说明
|
|
486
487
|
|
|
@@ -690,6 +691,23 @@ if len(matches) > 0:
|
|
|
690
691
|
print(f"找到匹配,置信度: {best.confidence}")
|
|
691
692
|
action.click(best.centerX, best.centerY, 100, False)
|
|
692
693
|
|
|
694
|
+
# 只要右下角那一个(界面上可能有很多份,不必全找出来)
|
|
695
|
+
corner = image.findImage(
|
|
696
|
+
"screen",
|
|
697
|
+
"btn.png",
|
|
698
|
+
0,
|
|
699
|
+
0,
|
|
700
|
+
0,
|
|
701
|
+
0,
|
|
702
|
+
0.9,
|
|
703
|
+
1,
|
|
704
|
+
5,
|
|
705
|
+
False,
|
|
706
|
+
{"orz": 5}, # 与找色相同:5 右下角起,纵向开始
|
|
707
|
+
)
|
|
708
|
+
if corner:
|
|
709
|
+
action.click(corner[0].centerX, corner[0].centerY, 100, False)
|
|
710
|
+
|
|
693
711
|
# 2) 缩放全分辨率找图:按「截模板设备宽 / 当前设备宽」计算比例
|
|
694
712
|
# 假设模板是在宽度 750 的设备上截的
|
|
695
713
|
template_device_width = 750
|