Skip to content

Commit 5f8bae0

Browse files
committed
(#204) Enabled passing of Image data to Screen#find
1 parent 19744ea commit 5f8bae0

File tree

4 files changed

+57
-62
lines changed

4 files changed

+57
-62
lines changed

Diff for: lib/match-request.class.spec.ts

+13-17
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,17 @@
1-
import { Image } from "./image.class";
2-
import { MatchRequest } from "./match-request.class";
3-
import { Region } from "./region.class";
1+
import {Image} from "./image.class";
2+
import {MatchRequest} from "./match-request.class";
43

54
describe("MatchRequest", () => {
6-
it("should default to multi-scale matching", () => {
7-
const SUT = new MatchRequest(
8-
new Image(100, 100,
9-
new ArrayBuffer(0), 3
10-
),
11-
"foo",
12-
new Region(
13-
0,
14-
0,
15-
100,
16-
100),
17-
0.99);
5+
it("should default to multi-scale matching", () => {
6+
const SUT = new MatchRequest(
7+
new Image(100, 100,
8+
new ArrayBuffer(0), 3
9+
),
10+
new Image(100, 100,
11+
new ArrayBuffer(0), 3
12+
),
13+
0.99);
1814

19-
expect(SUT.searchMultipleScales).toBeTruthy();
20-
});
15+
expect(SUT.searchMultipleScales).toBeTruthy();
16+
});
2117
});

Diff for: lib/match-request.class.ts

+1-3
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,9 @@
11
import { Image } from "./image.class";
2-
import { Region } from "./region.class";
32

43
export class MatchRequest {
54
constructor(
65
public readonly haystack: Image,
7-
public readonly pathToNeedle: string,
8-
public readonly searchRegion: Region,
6+
public readonly needle: Image,
97
public readonly confidence: number,
108
public readonly searchMultipleScales: boolean = true,
119
) {}

Diff for: lib/screen.class.spec.ts

+23-27
Original file line numberDiff line numberDiff line change
@@ -38,22 +38,21 @@ describe("Screen.", () => {
3838
// GIVEN
3939
const matchResult = new MatchResult(0.99, searchRegion);
4040
const SUT = new ScreenClass(providerRegistryMock);
41-
const imagePath = "test/path/to/image.png";
41+
const needle = new Image(100, 100, Buffer.from([]), 3);
4242

4343
const findMatchMock = jest.fn(() => Promise.resolve(matchResult));
4444
providerRegistryMock.getImageFinder = jest.fn(() => mockPartial<ImageFinderInterface>({
4545
findMatch: findMatchMock
4646
}));
4747

4848
// WHEN
49-
const resultRegion = SUT.find(imagePath);
49+
const resultRegion = SUT.find(needle);
5050

5151
// THEN
5252
await expect(resultRegion).resolves.toEqual(matchResult.location);
5353
const matchRequest = new MatchRequest(
5454
expect.any(Image),
55-
join(cwd(), imagePath),
56-
searchRegion,
55+
needle,
5756
SUT.config.confidence,
5857
true);
5958
expect(findMatchMock).toHaveBeenCalledWith(matchRequest);
@@ -69,11 +68,11 @@ describe("Screen.", () => {
6968

7069
const SUT = new ScreenClass(providerRegistryMock);
7170
const testCallback = jest.fn(() => Promise.resolve());
72-
const imagePath = "test/path/to/image.png";
73-
SUT.on(imagePath, testCallback);
71+
const needle = new Image(100, 100, Buffer.from([]), 3);
72+
SUT.on(needle, testCallback);
7473

7574
// WHEN
76-
await SUT.find(imagePath);
75+
await SUT.find(needle);
7776

7877
// THEN
7978
expect(testCallback).toBeCalledTimes(1);
@@ -91,12 +90,12 @@ describe("Screen.", () => {
9190
const SUT = new ScreenClass(providerRegistryMock);
9291
const testCallback = jest.fn(() => Promise.resolve());
9392
const secondCallback = jest.fn(() => Promise.resolve());
94-
const imagePath = "test/path/to/image.png";
95-
SUT.on(imagePath, testCallback);
96-
SUT.on(imagePath, secondCallback);
93+
const needle = new Image(100, 100, Buffer.from([]), 3);
94+
SUT.on(needle, testCallback);
95+
SUT.on(needle, secondCallback);
9796

9897
// WHEN
99-
await SUT.find(imagePath);
98+
await SUT.find(needle);
10099

101100
// THEN
102101
for (const callback of [testCallback, secondCallback]) {
@@ -160,18 +159,17 @@ describe("Screen.", () => {
160159

161160
const SUT = new ScreenClass(providerRegistryMock);
162161

163-
const imagePath = "test/path/to/image.png";
162+
const needle = new Image(100, 100, Buffer.from([]), 3);
164163
const parameters = new LocationParameters(undefined, minMatch);
165164

166165
// WHEN
167-
const resultRegion = SUT.find(imagePath, parameters);
166+
const resultRegion = SUT.find(needle, parameters);
168167

169168
// THEN
170169
await expect(resultRegion).resolves.toEqual(matchResult.location);
171170
const matchRequest = new MatchRequest(
172171
expect.any(Image),
173-
join(cwd(), imagePath),
174-
searchRegion,
172+
needle,
175173
minMatch,
176174
true);
177175
expect(findMatchMock).toHaveBeenCalledWith(matchRequest);
@@ -189,17 +187,16 @@ describe("Screen.", () => {
189187

190188
const SUT = new ScreenClass(providerRegistryMock);
191189

192-
const imagePath = "test/path/to/image.png";
190+
const needle = new Image(100, 100, Buffer.from([]), 3);
193191
const parameters = new LocationParameters(customSearchRegion);
194192
const expectedMatchRequest = new MatchRequest(
195193
expect.any(Image),
196-
join(cwd(), imagePath),
197-
customSearchRegion,
194+
needle,
198195
SUT.config.confidence,
199196
true);
200197

201198
// WHEN
202-
await SUT.find(imagePath, parameters);
199+
await SUT.find(needle, parameters);
203200

204201
// THEN
205202
expect(findMatchMock).toHaveBeenCalledWith(expectedMatchRequest);
@@ -214,17 +211,17 @@ describe("Screen.", () => {
214211
}));
215212

216213
const SUT = new ScreenClass(providerRegistryMock);
217-
const imagePath = "test/path/to/image.png";
214+
const needle = new Image(100, 100, Buffer.from([]), 3);
215+
218216
const parameters = new LocationParameters(searchRegion, undefined, false);
219217
const expectedMatchRequest = new MatchRequest(
220218
expect.any(Image),
221-
join(cwd(), imagePath),
222-
searchRegion,
219+
needle,
223220
SUT.config.confidence,
224221
false);
225222

226223
// WHEN
227-
await SUT.find(imagePath, parameters);
224+
await SUT.find(needle, parameters);
228225

229226
// THEN
230227
expect(findMatchMock).toHaveBeenCalledWith(expectedMatchRequest);
@@ -241,17 +238,16 @@ describe("Screen.", () => {
241238
}));
242239

243240
const SUT = new ScreenClass(providerRegistryMock);
244-
const imagePath = "test/path/to/image.png";
241+
const needle = new Image(100, 100, Buffer.from([]), 3);
245242
const parameters = new LocationParameters(customSearchRegion, minMatch);
246243
const expectedMatchRequest = new MatchRequest(
247244
expect.any(Image),
248-
join(cwd(), imagePath),
249-
customSearchRegion,
245+
needle,
250246
minMatch,
251247
true);
252248

253249
// WHEN
254-
await SUT.find(imagePath, parameters);
250+
await SUT.find(needle, parameters);
255251

256252
// THEN
257253
expect(findMatchMock).toHaveBeenCalledWith(expectedMatchRequest);

Diff for: lib/screen.class.ts

+20-15
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ export class ScreenClass {
5353
*/
5454
constructor(
5555
private providerRegistry: ProviderRegistry,
56-
private findHooks: Map<string, FindHookCallback[]> = new Map<string, FindHookCallback[]>()) {
56+
private findHooks: Map<Image, FindHookCallback[]> = new Map<Image, FindHookCallback[]>()) {
5757
}
5858

5959
/**
@@ -76,26 +76,31 @@ export class ScreenClass {
7676

7777
/**
7878
* {@link find} will search for a template image on a systems main screen
79-
* @param templateImageFilename Filename of the template image, relative to {@link ScreenClass.config.resourceDirectory}
79+
* @param templateImage Filename of the template image, relative to {@link ScreenClass.config.resourceDirectory}, or an {@link Image} instance
8080
* @param params {@link LocationParameters} which are used to fine tune search region and / or match confidence
8181
*/
8282
public async find(
83-
templateImageFilename: string,
83+
templateImage: string | Image,
8484
params?: LocationParameters,
8585
): Promise<Region> {
8686
const minMatch = (params && params.confidence) || this.config.confidence;
8787
const screenSize = await this.providerRegistry.getScreen().screenSize();
8888
const searchRegion = (params && params.searchRegion) || screenSize;
8989
const searchMultipleScales = (params && params.searchMultipleScales)
9090

91-
const fullPathToNeedle = normalize(join(this.config.resourceDirectory, templateImageFilename));
91+
let needle: Image;
92+
if (typeof templateImage === "string") {
93+
const fullPathToNeedle = normalize(join(this.config.resourceDirectory, templateImage));
94+
needle = await this.providerRegistry.getImageReader().load(fullPathToNeedle);
95+
} else {
96+
needle = templateImage;
97+
}
9298

93-
const screenImage = await this.providerRegistry.getScreen().grabScreen();
99+
const screenImage = await this.providerRegistry.getScreen().grabScreenRegion(searchRegion);
94100

95101
const matchRequest = new MatchRequest(
96102
screenImage,
97-
fullPathToNeedle,
98-
searchRegion,
103+
needle,
99104
minMatch,
100105
searchMultipleScales
101106
);
@@ -120,7 +125,7 @@ export class ScreenClass {
120125
validateSearchRegion(searchRegion, screenSize);
121126
const matchResult = await this.providerRegistry.getImageFinder().findMatch(matchRequest);
122127
if (matchResult.confidence >= minMatch) {
123-
const possibleHooks = this.findHooks.get(templateImageFilename) || [];
128+
const possibleHooks = this.findHooks.get(needle) || [];
124129
for (const hook of possibleHooks) {
125130
await hook(matchResult);
126131
}
@@ -137,14 +142,14 @@ export class ScreenClass {
137142
}
138143
} else {
139144
reject(
140-
`No match for ${templateImageFilename}. Required: ${minMatch}, given: ${
145+
`No match for ${typeof templateImage === "string" ? templateImage : 'image'}. Required: ${minMatch}, given: ${
141146
matchResult.confidence
142147
}`,
143148
);
144149
}
145150
} catch (e) {
146151
reject(
147-
`Searching for ${templateImageFilename} failed. Reason: '${e}'`,
152+
`Searching for ${typeof templateImage === "string" ? templateImage : 'image'} failed. Reason: '${e}'`,
148153
);
149154
}
150155
});
@@ -175,13 +180,13 @@ export class ScreenClass {
175180
}
176181

177182
/**
178-
* {@link on} registeres a callback which is triggered once a certain template image is found
179-
* @param templateImageFilename Template image to trigger the callback on
183+
* {@link on} registers a callback which is triggered once a certain template image is found
184+
* @param templateImage Template image to trigger the callback on
180185
* @param callback The {@link FindHookCallback} function to trigger
181186
*/
182-
public on(templateImageFilename: string, callback: FindHookCallback) {
183-
const existingHooks = this.findHooks.get(templateImageFilename) || [];
184-
this.findHooks.set(templateImageFilename, [...existingHooks, callback]);
187+
public on(templateImage: Image, callback: FindHookCallback) {
188+
const existingHooks = this.findHooks.get(templateImage) || [];
189+
this.findHooks.set(templateImage, [...existingHooks, callback]);
185190
}
186191

187192
/**

0 commit comments

Comments
 (0)