@aspiresys/visor 1.2.11 → 1.3.1
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/dist/index.d.ts +15 -52
- package/dist/index.js +16 -35
- package/dist/matcher.d.ts +3 -0
- package/dist/matcher.js +86 -14
- package/dist/mouse.d.ts +3 -9
- package/dist/mouse.js +3 -2
- package/dist/ocr.d.ts +2 -6
- package/dist/region.d.ts +9 -0
- package/dist/region.js +15 -0
- package/dist/text.d.ts +2 -12
- package/dist/text.js +2 -7
- package/dist/types.d.ts +165 -1
- package/dist/types.js +268 -0
- package/inspector/index.html +10 -4
- package/inspector/main.js +11 -6
- package/inspector/src/renderer.js +76 -72
- package/inspector/start.js +1 -4
- package/inspector/styles.css +44 -31
- package/inspector/templates/div.png +0 -0
- package/inspector/templates/match.png +0 -0
- package/inspector/templates/template.png +0 -0
- package/package.json +7 -1
- package/readme.md +182 -37
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Key, Button, Point } from "@nut-tree-fork/nut-js";
|
|
2
|
-
import { Region } from "./types";
|
|
3
|
-
|
|
2
|
+
import { Offset, Region } from "./types";
|
|
3
|
+
declare class Visor {
|
|
4
4
|
private mouse;
|
|
5
5
|
private keyboard;
|
|
6
6
|
Key: typeof Key;
|
|
@@ -32,10 +32,7 @@ export declare class Visor {
|
|
|
32
32
|
* height: 50
|
|
33
33
|
* });
|
|
34
34
|
*/
|
|
35
|
-
moveToRegion(region: Region, offset?:
|
|
36
|
-
x: number;
|
|
37
|
-
y: number;
|
|
38
|
-
}): Promise<void>;
|
|
35
|
+
moveToRegion(region: Region, offset?: Offset): Promise<void>;
|
|
39
36
|
/**
|
|
40
37
|
* Performs a left mouse click at the
|
|
41
38
|
* center of a specific screen region.
|
|
@@ -61,10 +58,7 @@ export declare class Visor {
|
|
|
61
58
|
* height: 50
|
|
62
59
|
* });
|
|
63
60
|
*/
|
|
64
|
-
clickRegion(region: Region, offset?:
|
|
65
|
-
x: number;
|
|
66
|
-
y: number;
|
|
67
|
-
}): Promise<void>;
|
|
61
|
+
clickRegion(region: Region, offset?: Offset): Promise<void>;
|
|
68
62
|
/**
|
|
69
63
|
* Performs a double left mouse click
|
|
70
64
|
* at the center of a specific
|
|
@@ -91,10 +85,7 @@ export declare class Visor {
|
|
|
91
85
|
* height: 50
|
|
92
86
|
* });
|
|
93
87
|
*/
|
|
94
|
-
doubleClickRegion(region: Region, offset?:
|
|
95
|
-
x: number;
|
|
96
|
-
y: number;
|
|
97
|
-
}): Promise<void>;
|
|
88
|
+
doubleClickRegion(region: Region, offset?: Offset): Promise<void>;
|
|
98
89
|
/**
|
|
99
90
|
* Performs a right mouse click at the
|
|
100
91
|
* center of a specific screen region.
|
|
@@ -120,10 +111,7 @@ export declare class Visor {
|
|
|
120
111
|
* height: 50
|
|
121
112
|
* });
|
|
122
113
|
*/
|
|
123
|
-
rightClickRegion(region: Region, offset?:
|
|
124
|
-
x: number;
|
|
125
|
-
y: number;
|
|
126
|
-
}): Promise<void>;
|
|
114
|
+
rightClickRegion(region: Region, offset?: Offset): Promise<void>;
|
|
127
115
|
/**
|
|
128
116
|
* Finds an image on screen using OpenCV
|
|
129
117
|
* and performs a left mouse click
|
|
@@ -154,10 +142,7 @@ export declare class Visor {
|
|
|
154
142
|
* @example
|
|
155
143
|
* await visor.click("./images/save.png", 0.9);
|
|
156
144
|
*/
|
|
157
|
-
click(image?: string, confidence?: number, offset?:
|
|
158
|
-
x: number;
|
|
159
|
-
y: number;
|
|
160
|
-
}): Promise<void>;
|
|
145
|
+
click(image?: string, confidence?: number, offset?: Offset): Promise<void>;
|
|
161
146
|
/**
|
|
162
147
|
* Performs a right mouse click.
|
|
163
148
|
*
|
|
@@ -182,10 +167,7 @@ export declare class Visor {
|
|
|
182
167
|
* @example
|
|
183
168
|
* await visor.rightClick();
|
|
184
169
|
*/
|
|
185
|
-
rightClick(image?: string, confidence?: number, offset?:
|
|
186
|
-
x: number;
|
|
187
|
-
y: number;
|
|
188
|
-
}): Promise<void>;
|
|
170
|
+
rightClick(image?: string, confidence?: number, offset?: Offset): Promise<void>;
|
|
189
171
|
/**
|
|
190
172
|
* Performs a double left mouse click.
|
|
191
173
|
*
|
|
@@ -211,10 +193,7 @@ export declare class Visor {
|
|
|
211
193
|
* @example
|
|
212
194
|
* await visor.doubleClick();
|
|
213
195
|
*/
|
|
214
|
-
doubleClick(image?: string, confidence?: number, offset?:
|
|
215
|
-
x: number;
|
|
216
|
-
y: number;
|
|
217
|
-
}): Promise<void>;
|
|
196
|
+
doubleClick(image?: string, confidence?: number, offset?: Offset): Promise<void>;
|
|
218
197
|
/**
|
|
219
198
|
* Finds the best matching image on screen
|
|
220
199
|
* using OpenCV template matching.
|
|
@@ -455,12 +434,7 @@ export declare class Visor {
|
|
|
455
434
|
* const region =
|
|
456
435
|
* await visor.findText("Submit");
|
|
457
436
|
*/
|
|
458
|
-
findText(text: string, index?: number, region?:
|
|
459
|
-
x: number;
|
|
460
|
-
y: number;
|
|
461
|
-
width: number;
|
|
462
|
-
height: number;
|
|
463
|
-
}): Promise<Region>;
|
|
437
|
+
findText(text: string, index?: number, region?: Region): Promise<Region>;
|
|
464
438
|
/**
|
|
465
439
|
* Checks whether specific text exists
|
|
466
440
|
* on screen using OCR.
|
|
@@ -474,12 +448,7 @@ export declare class Visor {
|
|
|
474
448
|
* const exists =
|
|
475
449
|
* await visor.existsText("Teams");
|
|
476
450
|
*/
|
|
477
|
-
existsText(text: string, region?:
|
|
478
|
-
x: number;
|
|
479
|
-
y: number;
|
|
480
|
-
width: number;
|
|
481
|
-
height: number;
|
|
482
|
-
}): Promise<boolean>;
|
|
451
|
+
existsText(text: string, region?: Region): Promise<boolean>;
|
|
483
452
|
/**
|
|
484
453
|
* Performs OCR on a specific
|
|
485
454
|
* screen region.
|
|
@@ -497,12 +466,7 @@ export declare class Visor {
|
|
|
497
466
|
* height: 300
|
|
498
467
|
* });
|
|
499
468
|
*/
|
|
500
|
-
readRegion(region:
|
|
501
|
-
x: number;
|
|
502
|
-
y: number;
|
|
503
|
-
width: number;
|
|
504
|
-
height: number;
|
|
505
|
-
}): Promise<any>;
|
|
469
|
+
readRegion(region: Region): Promise<any>;
|
|
506
470
|
/**
|
|
507
471
|
* Performs OCR on the entire screen
|
|
508
472
|
* using Tesseract OCR.
|
|
@@ -622,10 +586,7 @@ export declare class Visor {
|
|
|
622
586
|
* @example
|
|
623
587
|
* await visor.hover("menu.png");
|
|
624
588
|
*/
|
|
625
|
-
hover(image
|
|
626
|
-
x: number;
|
|
627
|
-
y: number;
|
|
628
|
-
}): Promise<void>;
|
|
589
|
+
hover(image: string, confidence?: number, offset?: Offset): Promise<void>;
|
|
629
590
|
/**
|
|
630
591
|
* Scrolls the mouse wheel downward.
|
|
631
592
|
*
|
|
@@ -1095,3 +1056,5 @@ export declare class Visor {
|
|
|
1095
1056
|
input(message: string, title?: string): Promise<string>;
|
|
1096
1057
|
}
|
|
1097
1058
|
export declare const visor: Visor;
|
|
1059
|
+
export { Region } from "./types";
|
|
1060
|
+
export type { Offset } from "./types";
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.Region = exports.visor = void 0;
|
|
4
4
|
const screen_1 = require("./screen");
|
|
5
5
|
const matcher_1 = require("./matcher");
|
|
6
6
|
const mouse_1 = require("./mouse");
|
|
@@ -73,10 +73,7 @@ class Visor {
|
|
|
73
73
|
* height: 50
|
|
74
74
|
* });
|
|
75
75
|
*/
|
|
76
|
-
async moveToRegion(region, offset
|
|
77
|
-
x: 0,
|
|
78
|
-
y: 0
|
|
79
|
-
}) {
|
|
76
|
+
async moveToRegion(region, offset) {
|
|
80
77
|
await (0, mouse_1.moveToRegion)(region, offset);
|
|
81
78
|
}
|
|
82
79
|
/**
|
|
@@ -104,10 +101,7 @@ class Visor {
|
|
|
104
101
|
* height: 50
|
|
105
102
|
* });
|
|
106
103
|
*/
|
|
107
|
-
async clickRegion(region, offset
|
|
108
|
-
x: 0,
|
|
109
|
-
y: 0
|
|
110
|
-
}) {
|
|
104
|
+
async clickRegion(region, offset) {
|
|
111
105
|
await (0, mouse_1.moveToRegion)(region, offset);
|
|
112
106
|
await this.mouse.click(this.Button.LEFT);
|
|
113
107
|
}
|
|
@@ -137,10 +131,7 @@ class Visor {
|
|
|
137
131
|
* height: 50
|
|
138
132
|
* });
|
|
139
133
|
*/
|
|
140
|
-
async doubleClickRegion(region, offset
|
|
141
|
-
x: 0,
|
|
142
|
-
y: 0
|
|
143
|
-
}) {
|
|
134
|
+
async doubleClickRegion(region, offset) {
|
|
144
135
|
await (0, mouse_1.moveToRegion)(region, offset);
|
|
145
136
|
await this.mouse.doubleClick(this.Button.LEFT);
|
|
146
137
|
}
|
|
@@ -169,10 +160,7 @@ class Visor {
|
|
|
169
160
|
* height: 50
|
|
170
161
|
* });
|
|
171
162
|
*/
|
|
172
|
-
async rightClickRegion(region, offset
|
|
173
|
-
x: 0,
|
|
174
|
-
y: 0
|
|
175
|
-
}) {
|
|
163
|
+
async rightClickRegion(region, offset) {
|
|
176
164
|
await (0, mouse_1.moveToRegion)(region, offset);
|
|
177
165
|
await this.mouse.click(this.Button.RIGHT);
|
|
178
166
|
}
|
|
@@ -206,10 +194,7 @@ class Visor {
|
|
|
206
194
|
* @example
|
|
207
195
|
* await visor.click("./images/save.png", 0.9);
|
|
208
196
|
*/
|
|
209
|
-
async click(image, confidence = 0.8, offset
|
|
210
|
-
x: 0,
|
|
211
|
-
y: 0
|
|
212
|
-
}) {
|
|
197
|
+
async click(image, confidence = 0.8, offset) {
|
|
213
198
|
this.checkConfig();
|
|
214
199
|
if (!image) {
|
|
215
200
|
await this.mouse.click(this.Button.LEFT);
|
|
@@ -247,10 +232,7 @@ class Visor {
|
|
|
247
232
|
* @example
|
|
248
233
|
* await visor.rightClick();
|
|
249
234
|
*/
|
|
250
|
-
async rightClick(image, confidence = 0.8, offset
|
|
251
|
-
x: 0,
|
|
252
|
-
y: 0
|
|
253
|
-
}) {
|
|
235
|
+
async rightClick(image, confidence = 0.8, offset) {
|
|
254
236
|
this.checkConfig();
|
|
255
237
|
if (image) {
|
|
256
238
|
const region = await this.find(image, confidence);
|
|
@@ -287,10 +269,7 @@ class Visor {
|
|
|
287
269
|
* @example
|
|
288
270
|
* await visor.doubleClick();
|
|
289
271
|
*/
|
|
290
|
-
async doubleClick(image, confidence = 0.8, offset
|
|
291
|
-
x: 0,
|
|
292
|
-
y: 0
|
|
293
|
-
}) {
|
|
272
|
+
async doubleClick(image, confidence = 0.8, offset) {
|
|
294
273
|
this.checkConfig();
|
|
295
274
|
if (image) {
|
|
296
275
|
const region = await this.find(image, confidence);
|
|
@@ -632,7 +611,11 @@ CONF:${m.confidence.toFixed(3)}
|
|
|
632
611
|
*/
|
|
633
612
|
async findText(text, index = 0, region) {
|
|
634
613
|
this.checkConfig();
|
|
635
|
-
|
|
614
|
+
const match = await (0, text_1.findText)(text, index, region);
|
|
615
|
+
if (match != null && region) {
|
|
616
|
+
return match.offset(region.x, region.y);
|
|
617
|
+
}
|
|
618
|
+
return match;
|
|
636
619
|
}
|
|
637
620
|
/**
|
|
638
621
|
* Checks whether specific text exists
|
|
@@ -815,10 +798,7 @@ CONF:${m.confidence.toFixed(3)}
|
|
|
815
798
|
* @example
|
|
816
799
|
* await visor.hover("menu.png");
|
|
817
800
|
*/
|
|
818
|
-
async hover(image, confidence = 0.8, offset
|
|
819
|
-
x: 0,
|
|
820
|
-
y: 0
|
|
821
|
-
}) {
|
|
801
|
+
async hover(image, confidence = 0.8, offset) {
|
|
822
802
|
this.checkConfig();
|
|
823
803
|
const region = await this.find(image, confidence);
|
|
824
804
|
if (!region) {
|
|
@@ -1412,5 +1392,6 @@ CONF:${m.confidence.toFixed(3)}
|
|
|
1412
1392
|
return await (0, dialog_1.prompt)(message, title);
|
|
1413
1393
|
}
|
|
1414
1394
|
}
|
|
1415
|
-
exports.Visor = Visor;
|
|
1416
1395
|
exports.visor = new Visor();
|
|
1396
|
+
var types_1 = require("./types");
|
|
1397
|
+
Object.defineProperty(exports, "Region", { enumerable: true, get: function () { return types_1.Region; } });
|
package/dist/matcher.d.ts
CHANGED
|
@@ -3,3 +3,6 @@ export declare function loadTemplate(path: string): Promise<any>;
|
|
|
3
3
|
export declare function loadScreen(path: string): Promise<any>;
|
|
4
4
|
export declare function matchTemplate(screen: any, template: any, confidence?: number): Region | null;
|
|
5
5
|
export declare function findAllMatches(screen: any, template: any, confidence?: number): Region[];
|
|
6
|
+
export declare function findAllInspectorMatches(screen: any, template: any, confidence?: number): Region[];
|
|
7
|
+
export declare function matchInspectorTemplate(screen: any, template: any, confidence?: number, multiScale?: boolean): Region | null;
|
|
8
|
+
export declare function cropMat(screen: any, region: Region): any;
|
package/dist/matcher.js
CHANGED
|
@@ -7,10 +7,14 @@ exports.loadTemplate = loadTemplate;
|
|
|
7
7
|
exports.loadScreen = loadScreen;
|
|
8
8
|
exports.matchTemplate = matchTemplate;
|
|
9
9
|
exports.findAllMatches = findAllMatches;
|
|
10
|
+
exports.findAllInspectorMatches = findAllInspectorMatches;
|
|
11
|
+
exports.matchInspectorTemplate = matchInspectorTemplate;
|
|
12
|
+
exports.cropMat = cropMat;
|
|
10
13
|
const fs_1 = __importDefault(require("fs"));
|
|
11
14
|
const pngjs_1 = require("pngjs");
|
|
12
15
|
const cv = require("@techstark/opencv-js");
|
|
13
16
|
const templateCache = new Map();
|
|
17
|
+
const types_1 = require("./types");
|
|
14
18
|
const logger_1 = require("./logger");
|
|
15
19
|
async function loadTemplate(path) {
|
|
16
20
|
if (templateCache.has(path)) {
|
|
@@ -62,13 +66,7 @@ function matchTemplate(screen, template, confidence = 0.8) {
|
|
|
62
66
|
(0, logger_1.log)(`[MATCH] Scale ${scale} -> ${maxVal}`);
|
|
63
67
|
result.delete();
|
|
64
68
|
if (maxVal >= confidence && (!bestMatch || maxVal > bestMatch.confidence)) {
|
|
65
|
-
bestMatch =
|
|
66
|
-
x: maxLoc.x,
|
|
67
|
-
y: maxLoc.y,
|
|
68
|
-
width: resizedTemplate.cols,
|
|
69
|
-
height: resizedTemplate.rows,
|
|
70
|
-
confidence: maxVal,
|
|
71
|
-
};
|
|
69
|
+
bestMatch = new types_1.Region(maxLoc.x, maxLoc.y, resizedTemplate.cols, resizedTemplate.rows, maxVal);
|
|
72
70
|
if (maxVal >= 0.98) {
|
|
73
71
|
resizedTemplate.delete();
|
|
74
72
|
(0, logger_1.log)(`[MATCH] Total: ${Date.now() - start} ms`);
|
|
@@ -88,13 +86,7 @@ function findAllMatches(screen, template, confidence = 0.8) {
|
|
|
88
86
|
for (let x = 0; x < result.cols; x++) {
|
|
89
87
|
const score = result.floatAt(y, x);
|
|
90
88
|
if (score >= confidence) {
|
|
91
|
-
matches.push(
|
|
92
|
-
x,
|
|
93
|
-
y,
|
|
94
|
-
width: template.cols,
|
|
95
|
-
height: template.rows,
|
|
96
|
-
confidence: score,
|
|
97
|
-
});
|
|
89
|
+
matches.push(new types_1.Region(x, y, template.cols, template.rows, score));
|
|
98
90
|
}
|
|
99
91
|
}
|
|
100
92
|
}
|
|
@@ -113,3 +105,83 @@ function findAllMatches(screen, template, confidence = 0.8) {
|
|
|
113
105
|
result.delete();
|
|
114
106
|
return filtered;
|
|
115
107
|
}
|
|
108
|
+
function findAllInspectorMatches(screen, template, confidence = 0.8) {
|
|
109
|
+
const result = new cv.Mat();
|
|
110
|
+
cv.matchTemplate(screen, template, result, cv.TM_CCOEFF_NORMED);
|
|
111
|
+
const matches = [];
|
|
112
|
+
for (let y = 0; y < result.rows; y++) {
|
|
113
|
+
for (let x = 0; x < result.cols; x++) {
|
|
114
|
+
const score = result.floatAt(y, x);
|
|
115
|
+
if (score >= confidence) {
|
|
116
|
+
matches.push(new types_1.Region(x, y, template.cols, template.rows, score));
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
const filtered = [];
|
|
121
|
+
for (const match of matches) {
|
|
122
|
+
const tooClose = filtered.some((existing) => {
|
|
123
|
+
const dx = Math.abs(existing.x - match.x);
|
|
124
|
+
const dy = Math.abs(existing.y - match.y);
|
|
125
|
+
return dx < 10 && dy < 10;
|
|
126
|
+
});
|
|
127
|
+
if (!tooClose) {
|
|
128
|
+
filtered.push(match);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
result.delete();
|
|
132
|
+
return filtered;
|
|
133
|
+
}
|
|
134
|
+
function matchInspectorTemplate(screen, template, confidence = 0.8, multiScale = false) {
|
|
135
|
+
if (multiScale) {
|
|
136
|
+
const start = Date.now();
|
|
137
|
+
const scales = [1.0, 0.9, 1.1, 0.8, 1.2, 0.7, 1.3, 0.6, 1.4, 0.5, 1.5];
|
|
138
|
+
let bestMatch = null;
|
|
139
|
+
for (const scale of scales) {
|
|
140
|
+
const resizedTemplate = resizeTemplate(template, scale);
|
|
141
|
+
if (resizedTemplate.cols > screen.cols ||
|
|
142
|
+
resizedTemplate.rows > screen.rows) {
|
|
143
|
+
resizedTemplate.delete();
|
|
144
|
+
continue;
|
|
145
|
+
}
|
|
146
|
+
const result = new cv.Mat();
|
|
147
|
+
cv.matchTemplate(screen, resizedTemplate, result, cv.TM_CCOEFF_NORMED);
|
|
148
|
+
const { maxLoc, maxVal } = cv.minMaxLoc(result);
|
|
149
|
+
(0, logger_1.log)(`[MATCH] Scale ${scale} -> ${maxVal}`);
|
|
150
|
+
result.delete();
|
|
151
|
+
if (maxVal >= confidence && (!bestMatch || maxVal > bestMatch.confidence)) {
|
|
152
|
+
bestMatch = new types_1.Region(maxLoc.x, maxLoc.y, resizedTemplate.cols, resizedTemplate.rows, maxVal);
|
|
153
|
+
if (maxVal >= 0.98) {
|
|
154
|
+
resizedTemplate.delete();
|
|
155
|
+
(0, logger_1.log)(`[MATCH] Total: ${Date.now() - start} ms`);
|
|
156
|
+
return bestMatch;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
resizedTemplate.delete();
|
|
160
|
+
}
|
|
161
|
+
(0, logger_1.log)(`[MATCH] Total: ${Date.now() - start} ms`);
|
|
162
|
+
return bestMatch;
|
|
163
|
+
}
|
|
164
|
+
else {
|
|
165
|
+
const start = Date.now();
|
|
166
|
+
const result = new cv.Mat();
|
|
167
|
+
cv.matchTemplate(screen, template, result, cv.TM_CCOEFF_NORMED);
|
|
168
|
+
const { maxLoc, maxVal } = cv.minMaxLoc(result);
|
|
169
|
+
result.delete();
|
|
170
|
+
if (maxVal >= confidence) {
|
|
171
|
+
return new types_1.Region(maxLoc.x, maxLoc.y, template.cols, template.rows, maxVal);
|
|
172
|
+
}
|
|
173
|
+
(0, logger_1.log)(`[MATCH] Total: ${Date.now() - start} ms`);
|
|
174
|
+
return null;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
function cropMat(screen, region) {
|
|
178
|
+
const x = Math.max(0, Math.floor(region.x));
|
|
179
|
+
const y = Math.max(0, Math.floor(region.y));
|
|
180
|
+
const width = Math.min(Math.floor(region.width), screen.cols - x);
|
|
181
|
+
const height = Math.min(Math.floor(region.height), screen.rows - y);
|
|
182
|
+
const rect = new cv.Rect(x, y, width, height);
|
|
183
|
+
const croppedMat = screen.roi(rect);
|
|
184
|
+
const isolatedMat = croppedMat.clone();
|
|
185
|
+
croppedMat.delete();
|
|
186
|
+
return isolatedMat;
|
|
187
|
+
}
|
package/dist/mouse.d.ts
CHANGED
|
@@ -1,9 +1,3 @@
|
|
|
1
|
-
import { Region } from "./types";
|
|
2
|
-
export declare function moveToRegion(region: Region, offset?:
|
|
3
|
-
|
|
4
|
-
y: number;
|
|
5
|
-
}): Promise<void>;
|
|
6
|
-
export declare function clickRegion(region: Region, offset?: {
|
|
7
|
-
x: number;
|
|
8
|
-
y: number;
|
|
9
|
-
}): Promise<void>;
|
|
1
|
+
import { Offset, Region } from "./types";
|
|
2
|
+
export declare function moveToRegion(region: Region, offset?: Offset): Promise<void>;
|
|
3
|
+
export declare function clickRegion(region: Region, offset?: Offset): Promise<void>;
|
package/dist/mouse.js
CHANGED
|
@@ -10,8 +10,9 @@ async function moveToRegion(region, offset = {
|
|
|
10
10
|
y: 0
|
|
11
11
|
}) {
|
|
12
12
|
const scaleFactor = config_1.visorConfig.scaleFactor;
|
|
13
|
-
const
|
|
14
|
-
const
|
|
13
|
+
const center = region.center();
|
|
14
|
+
const centerX = Math.floor((center.x + offset.x) / scaleFactor);
|
|
15
|
+
const centerY = Math.floor((center.y + offset.y) / scaleFactor);
|
|
15
16
|
(0, logger_1.log)("[MOUSE] Moving mouse to:", centerX, centerY);
|
|
16
17
|
await nut_js_1.mouse.move([new nut_js_1.Point(centerX, centerY)]);
|
|
17
18
|
}
|
package/dist/ocr.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { Region } from "./types";
|
|
1
2
|
/**
|
|
2
3
|
* Terminates OCR worker manually.
|
|
3
4
|
*
|
|
@@ -15,9 +16,4 @@ export declare function terminateOCR(): Promise<void>;
|
|
|
15
16
|
* - sharp preprocessing
|
|
16
17
|
* - Tesseract OCR
|
|
17
18
|
*/
|
|
18
|
-
export declare function extractTextFromRegion(region?:
|
|
19
|
-
x: number;
|
|
20
|
-
y: number;
|
|
21
|
-
width: number;
|
|
22
|
-
height: number;
|
|
23
|
-
}): Promise<any>;
|
|
19
|
+
export declare function extractTextFromRegion(region?: Region): Promise<any>;
|
package/dist/region.d.ts
ADDED
package/dist/region.js
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Region = void 0;
|
|
4
|
+
class Region {
|
|
5
|
+
constructor(x, y, width, height, confidence = 1) {
|
|
6
|
+
this.x = x;
|
|
7
|
+
this.y = y;
|
|
8
|
+
this.width = width;
|
|
9
|
+
this.height = height;
|
|
10
|
+
this.confidence = confidence;
|
|
11
|
+
}
|
|
12
|
+
center() {
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
exports.Region = Region;
|
package/dist/text.d.ts
CHANGED
|
@@ -1,13 +1,3 @@
|
|
|
1
1
|
import { Region } from "./types";
|
|
2
|
-
export declare function findText(text: string, index?: number, region?:
|
|
3
|
-
|
|
4
|
-
y: number;
|
|
5
|
-
width: number;
|
|
6
|
-
height: number;
|
|
7
|
-
}): Promise<Region | null>;
|
|
8
|
-
export declare function existsText(text: string, region?: {
|
|
9
|
-
x: number;
|
|
10
|
-
y: number;
|
|
11
|
-
width: number;
|
|
12
|
-
height: number;
|
|
13
|
-
}): Promise<boolean>;
|
|
2
|
+
export declare function findText(text: string, index?: number, region?: Region): Promise<Region | null>;
|
|
3
|
+
export declare function existsText(text: string, region?: Region): Promise<boolean>;
|
package/dist/text.js
CHANGED
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.findText = findText;
|
|
4
4
|
exports.existsText = existsText;
|
|
5
5
|
const ocr_1 = require("./ocr");
|
|
6
|
+
const types_1 = require("./types");
|
|
6
7
|
async function findText(text, index = 0, region) {
|
|
7
8
|
const result = await (0, ocr_1.extractTextFromRegion)(region);
|
|
8
9
|
const tsv = result.tsv;
|
|
@@ -62,13 +63,7 @@ async function findText(text, index = 0, region) {
|
|
|
62
63
|
const maxX = Math.max(...regionWords.map((w) => w.x + w.width));
|
|
63
64
|
const maxY = Math.max(...regionWords.map((w) => w.y + w.height));
|
|
64
65
|
const avgConfidence = words.reduce((sum, w) => sum + w.confidence, 0) / words.length;
|
|
65
|
-
matches.push(
|
|
66
|
-
x: minX,
|
|
67
|
-
y: minY,
|
|
68
|
-
width: maxX - minX,
|
|
69
|
-
height: maxY - minY,
|
|
70
|
-
confidence: avgConfidence,
|
|
71
|
-
});
|
|
66
|
+
matches.push(new types_1.Region(minX, minY, maxX - minX, maxY - minY, avgConfidence));
|
|
72
67
|
}
|
|
73
68
|
}
|
|
74
69
|
matches.sort((a, b) => a.y - b.y || a.x - b.x);
|
package/dist/types.d.ts
CHANGED
|
@@ -1,10 +1,174 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Represents a rectangular screen region.
|
|
3
|
+
*
|
|
4
|
+
* A Region can be returned by:
|
|
5
|
+
* - image matching
|
|
6
|
+
* - OCR text search
|
|
7
|
+
* - region-based searches
|
|
8
|
+
*
|
|
9
|
+
* Provides helper methods for:
|
|
10
|
+
* - mouse interaction
|
|
11
|
+
* - OCR operations
|
|
12
|
+
* - image matching
|
|
13
|
+
* - geometry calculations
|
|
14
|
+
* Example:
|
|
15
|
+
*
|
|
16
|
+
* const dialog = await visor.find("dialog.png");
|
|
17
|
+
*
|
|
18
|
+
* const saveButton = await dialog.find("save.png");
|
|
19
|
+
*
|
|
20
|
+
* await saveButton.click();
|
|
21
|
+
*
|
|
22
|
+
* const text = await dialog.findText("Submit");
|
|
23
|
+
*/
|
|
24
|
+
export declare class Region {
|
|
2
25
|
x: number;
|
|
3
26
|
y: number;
|
|
4
27
|
width: number;
|
|
5
28
|
height: number;
|
|
6
29
|
confidence: number;
|
|
30
|
+
private static configWarningShown;
|
|
31
|
+
constructor(x: number, y: number, width: number, height: number, confidence?: number);
|
|
32
|
+
private checkConfig;
|
|
33
|
+
/**
|
|
34
|
+
* Returns the center point of the region.
|
|
35
|
+
*
|
|
36
|
+
* Useful for:
|
|
37
|
+
* - mouse movement
|
|
38
|
+
* - coordinate calculations
|
|
39
|
+
* - custom interactions
|
|
40
|
+
*/
|
|
41
|
+
center(): {
|
|
42
|
+
x: number;
|
|
43
|
+
y: number;
|
|
44
|
+
};
|
|
45
|
+
/**
|
|
46
|
+
* Moves the mouse to the center of the region.
|
|
47
|
+
*
|
|
48
|
+
* Mouse coordinates are automatically
|
|
49
|
+
* adjusted for display scaling.
|
|
50
|
+
*/
|
|
51
|
+
move(): Promise<void>;
|
|
52
|
+
/**
|
|
53
|
+
* Performs a left click on the region.
|
|
54
|
+
*
|
|
55
|
+
* Clicks the center of the region by default.
|
|
56
|
+
*
|
|
57
|
+
* Optional offset can be supplied to click
|
|
58
|
+
* a specific position relative to the center.
|
|
59
|
+
*/
|
|
60
|
+
click(offset?: Offset): Promise<void>;
|
|
61
|
+
/**
|
|
62
|
+
* Performs a double left click on the region.
|
|
63
|
+
*
|
|
64
|
+
* Optional offset can be supplied to click
|
|
65
|
+
* a specific position relative to the center.
|
|
66
|
+
*/
|
|
67
|
+
doubleClick(offset?: Offset): Promise<void>;
|
|
68
|
+
/**
|
|
69
|
+
* Performs a right click on the region.
|
|
70
|
+
*
|
|
71
|
+
* Optional offset can be supplied to click
|
|
72
|
+
* a specific position relative to the center.
|
|
73
|
+
*/
|
|
74
|
+
rightClick(offset?: Offset): Promise<void>;
|
|
75
|
+
/**
|
|
76
|
+
* Checks whether the supplied coordinates
|
|
77
|
+
* are located inside this region.
|
|
78
|
+
*
|
|
79
|
+
* Returns:
|
|
80
|
+
* - true if inside
|
|
81
|
+
* - false otherwise
|
|
82
|
+
*/
|
|
83
|
+
contains(x: number, y: number): boolean;
|
|
84
|
+
/**
|
|
85
|
+
* Creates a new Region shifted by the
|
|
86
|
+
* supplied x and y offsets.
|
|
87
|
+
*
|
|
88
|
+
* Original region remains unchanged.
|
|
89
|
+
*/
|
|
90
|
+
offset(x: number, y: number): Region;
|
|
91
|
+
/**
|
|
92
|
+
* Checks whether this region overlaps
|
|
93
|
+
* with another region.
|
|
94
|
+
*
|
|
95
|
+
* Returns:
|
|
96
|
+
* - true if regions intersect
|
|
97
|
+
* - false otherwise
|
|
98
|
+
*/
|
|
99
|
+
intersects(region: Region): boolean;
|
|
100
|
+
/**
|
|
101
|
+
* Returns the total area of the region
|
|
102
|
+
* in pixels.
|
|
103
|
+
*/
|
|
104
|
+
area(): number;
|
|
105
|
+
/**
|
|
106
|
+
* Extracts OCR text from this region.
|
|
107
|
+
*
|
|
108
|
+
* Returns full OCR output including:
|
|
109
|
+
* - text
|
|
110
|
+
* - TSV data
|
|
111
|
+
* - HOCR data
|
|
112
|
+
* - block information
|
|
113
|
+
*/
|
|
114
|
+
readText(): Promise<any>;
|
|
115
|
+
/**
|
|
116
|
+
* Searches for text within this region.
|
|
117
|
+
*
|
|
118
|
+
* Returns the matching text region
|
|
119
|
+
* if found, otherwise null.
|
|
120
|
+
*
|
|
121
|
+
* Supports selecting a specific match
|
|
122
|
+
* using the index parameter.
|
|
123
|
+
*/
|
|
124
|
+
findText(text: string, index?: number): Promise<Region>;
|
|
125
|
+
/**
|
|
126
|
+
* Checks whether the supplied text
|
|
127
|
+
* exists within this region.
|
|
128
|
+
*
|
|
129
|
+
* Returns:
|
|
130
|
+
* - true if found
|
|
131
|
+
* - false otherwise
|
|
132
|
+
*/
|
|
133
|
+
existsText(text: string): Promise<boolean>;
|
|
134
|
+
/**
|
|
135
|
+
* Searches for an image within this region.
|
|
136
|
+
*
|
|
137
|
+
* Matching is performed only inside
|
|
138
|
+
* the current region, improving speed
|
|
139
|
+
* and reducing false positives.
|
|
140
|
+
*
|
|
141
|
+
* Returns:
|
|
142
|
+
* - matching Region if found
|
|
143
|
+
* - null otherwise
|
|
144
|
+
*/
|
|
145
|
+
find(image: string, confidence?: number): Promise<Region>;
|
|
146
|
+
/**
|
|
147
|
+
* Finds all image matches within this region.
|
|
148
|
+
*
|
|
149
|
+
* Matching is performed only inside
|
|
150
|
+
* the current region.
|
|
151
|
+
*
|
|
152
|
+
* Returns an array of matching regions.
|
|
153
|
+
*/
|
|
154
|
+
findAll(image: string, confidence?: number): Promise<Region[]>;
|
|
155
|
+
/**
|
|
156
|
+
* Checks whether an image exists
|
|
157
|
+
* within this region.
|
|
158
|
+
*
|
|
159
|
+
* Returns:
|
|
160
|
+
* - true if found
|
|
161
|
+
* - false otherwise
|
|
162
|
+
*/
|
|
163
|
+
exists(image: string, confidence?: number): Promise<boolean>;
|
|
7
164
|
}
|
|
165
|
+
/**
|
|
166
|
+
* Represents an offset relative to
|
|
167
|
+
* a region's center point.
|
|
168
|
+
*
|
|
169
|
+
* Useful for clicking specific locations
|
|
170
|
+
* within a matched region.
|
|
171
|
+
*/
|
|
8
172
|
export interface Offset {
|
|
9
173
|
x: number;
|
|
10
174
|
y: number;
|