Skip to content

Commit 21f1971

Browse files
authored
Feature/451/bits per pixel (#452)
* (#451) Extended image class with bitPerPixel and byteWidth properties * (#451) Adjusted image tests to new interface * (#451) Adjusted usages of Image class to provide required new data, added type predicate to highlight and grabRegion * (#451) Adjusted tests
1 parent dfa57d6 commit 21f1971

11 files changed

+253
-51
lines changed

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

+20-10
Original file line numberDiff line numberDiff line change
@@ -14,38 +14,46 @@ afterEach(() => {
1414

1515
describe("Image class", () => {
1616
it("should return alphachannel = true for > 3 channels", () => {
17-
const SUT = new Image(200, 200, Buffer.from([123]), 4, "id");
17+
const SUT = new Image(200, 200, Buffer.from([123]), 4, "id", 4, 200 * 4);
1818
expect(SUT.hasAlphaChannel).toBeTruthy();
1919
});
2020

2121
it("should return alphachannel = false for <= 3 channels", () => {
22-
const SUT = new Image(200, 200, Buffer.from([123]), 3, "id");
22+
const SUT = new Image(200, 200, Buffer.from([123]), 3, "id", 4, 200 * 4);
2323
expect(SUT.hasAlphaChannel).toBeFalsy();
2424
});
2525
it("should return alphachannel = false for <= 3 channels", () => {
26-
const SUT = new Image(200, 200, Buffer.from([123]), 2, "id");
26+
const SUT = new Image(200, 200, Buffer.from([123]), 2, "id", 4, 200 * 4);
2727
expect(SUT.hasAlphaChannel).toBeFalsy();
2828
});
2929
it("should return alphachannel = false for <= 3 channels", () => {
30-
const SUT = new Image(200, 200, Buffer.from([123]), 1, "id");
30+
const SUT = new Image(200, 200, Buffer.from([123]), 1, "id", 4, 200 * 4);
3131
expect(SUT.hasAlphaChannel).toBeFalsy();
3232
});
3333

3434
it("should throw for <= 0 channels", () => {
35-
expect(() => new Image(200, 200, Buffer.from([123]), 0, "id")).toThrowError(
36-
"Channel <= 0"
37-
);
35+
expect(
36+
() => new Image(200, 200, Buffer.from([123]), 0, "id", 4, 200 * 4)
37+
).toThrowError("Channel <= 0");
3838
});
3939

4040
it("should have a default pixel density of 1.0", () => {
41-
const SUT = new Image(200, 200, Buffer.from([123]), 1, "id");
41+
const SUT = new Image(200, 200, Buffer.from([123]), 1, "id", 4, 200 * 4);
4242
expect(SUT.pixelDensity).toEqual({ scaleX: 1.0, scaleY: 1.0 });
4343
});
4444

4545
describe("Colormode", () => {
4646
it("should not try to convert an image to BGR if it already has the correct color mode", async () => {
4747
// GIVEN
48-
const bgrImage = new Image(100, 100, Buffer.from([]), 3, "testImage");
48+
const bgrImage = new Image(
49+
100,
50+
100,
51+
Buffer.from([]),
52+
3,
53+
"testImage",
54+
4,
55+
200 * 4
56+
);
4957

5058
// WHEN
5159
const convertedImage = await bgrImage.toBGR();
@@ -63,6 +71,8 @@ describe("Image class", () => {
6371
Buffer.from([]),
6472
3,
6573
"testImage",
74+
4,
75+
200 * 4,
6676
ColorMode.RGB
6777
);
6878

@@ -78,7 +88,7 @@ describe("Image class", () => {
7888
describe("isImage typeguard", () => {
7989
it("should identify an Image", () => {
8090
// GIVEN
81-
const img = new Image(100, 100, Buffer.from([]), 4, "foo");
91+
const img = new Image(100, 100, Buffer.from([]), 4, "foo", 4, 200 * 4);
8292

8393
// WHEN
8494
const result = isImage(img);

Diff for: lib/image.class.ts

+38-4
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ export class Image {
1212
* @param data Generic {@link Image} data
1313
* @param channels Amount of {@link Image} channels
1414
* @param id Image identifier
15+
* @param bitsPerPixel Number of bits per single pixel
16+
* @param byteWidth Total number of bytes per image line
1517
* @param colorMode An images color mode, defaults to {@link ColorMode.BGR}
1618
* @param pixelDensity Object containing scale info to work with e.g. Retina display data where the reported display size and pixel size differ (Default: {scaleX: 1.0, scaleY: 1.0})
1719
*/
@@ -21,6 +23,8 @@ export class Image {
2123
public readonly data: Buffer,
2224
public readonly channels: number,
2325
public readonly id: string,
26+
public readonly bitsPerPixel: number,
27+
public readonly byteWidth: number,
2428
public readonly colorMode: ColorMode = ColorMode.BGR,
2529
public readonly pixelDensity: { scaleX: number; scaleY: number } = {
2630
scaleX: 1.0,
@@ -53,6 +57,8 @@ export class Image {
5357
rgbImage.bitmap.data,
5458
this.channels,
5559
this.id,
60+
this.bitsPerPixel,
61+
this.byteWidth,
5662
ColorMode.RGB,
5763
this.pixelDensity
5864
);
@@ -72,6 +78,8 @@ export class Image {
7278
rgbImage.bitmap.data,
7379
this.channels,
7480
this.id,
81+
this.bitsPerPixel,
82+
this.byteWidth,
7583
ColorMode.BGR,
7684
this.pixelDensity
7785
);
@@ -85,15 +93,41 @@ export class Image {
8593
height: number,
8694
data: Buffer,
8795
channels: number,
88-
id: string
96+
id: string,
97+
bitsPerPixel: number,
98+
byteWidth: number
8999
): Image {
90-
const rgbImage = new Image(width, height, data, channels, id);
100+
const rgbImage = new Image(
101+
width,
102+
height,
103+
data,
104+
channels,
105+
id,
106+
bitsPerPixel,
107+
byteWidth
108+
);
91109
const jimpImage = imageToJimp(rgbImage);
92-
return new Image(width, height, jimpImage.bitmap.data, channels, id);
110+
return new Image(
111+
width,
112+
height,
113+
jimpImage.bitmap.data,
114+
channels,
115+
id,
116+
bitsPerPixel,
117+
byteWidth
118+
);
93119
}
94120
}
95121

96-
const testImage = new Image(100, 100, Buffer.from([]), 4, "typeCheck");
122+
const testImage = new Image(
123+
100,
124+
100,
125+
Buffer.from([]),
126+
4,
127+
"typeCheck",
128+
4,
129+
100 * 4
130+
);
97131
const imageKeys = Object.keys(testImage);
98132

99133
export function isImage(possibleImage: any): possibleImage is Image {

Diff for: lib/imageResources.function.ts

+2
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ export async function fetchFromUrl(url: string | URL): Promise<Image> {
3838
image.bitmap.data,
3939
4,
4040
imageUrl.href,
41+
image.bitmap.data.length / (image.bitmap.width * image.bitmap.height),
42+
image.bitmap.data.length / image.bitmap.height,
4143
ColorMode.RGB
4244
);
4345
})

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

+2-2
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ jest.mock("jimp", () => {});
66
describe("MatchRequest", () => {
77
it("should default to multi-scale matching", () => {
88
const SUT = new MatchRequest(
9-
new Image(100, 100, Buffer.from([]), 3, "haystack_image"),
10-
new Image(100, 100, Buffer.from([]), 3, "needle_image"),
9+
new Image(100, 100, Buffer.from([]), 3, "haystack_image", 4, 100 * 4),
10+
new Image(100, 100, Buffer.from([]), 3, "needle_image", 4, 100 * 4),
1111
0.99
1212
);
1313

Diff for: lib/provider/io/imageToJimp.function.spec.ts

+3-1
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,9 @@ describe("imageToJimp", () => {
3131
1,
3232
Buffer.from([0, 0, 0]),
3333
3,
34-
"input_image"
34+
"input_image",
35+
4,
36+
4
3537
);
3638

3739
// WHEN

Diff for: lib/provider/io/jimp-image-reader.class.ts

+3
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,9 @@ export default class implements ImageReader {
2727
jimpImage.bitmap.data,
2828
jimpImage.hasAlpha() ? 4 : 3,
2929
parameters,
30+
jimpImage.bitmap.data.length /
31+
(jimpImage.bitmap.width * jimpImage.bitmap.height),
32+
jimpImage.bitmap.data.length / jimpImage.bitmap.height,
3033
ColorMode.BGR
3134
)
3235
);

Diff for: lib/provider/io/jimp-image-writer.class.spec.ts

+9-1
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,15 @@ describe("Jimp image writer", () => {
2525
it("should reject on writing failures", async () => {
2626
// GIVEN
2727
const outputFileName = "/does/not/compute.png";
28-
const outputFile = new Image(100, 200, Buffer.from([]), 3, outputFileName);
28+
const outputFile = new Image(
29+
100,
30+
200,
31+
Buffer.from([]),
32+
3,
33+
outputFileName,
34+
4,
35+
100 * 4
36+
);
2937
const writeMock = jest.fn(() => Promise.resolve(new Jimp()));
3038
const scanMock = jest.fn();
3139
Jimp.prototype.scan = scanMock;

Diff for: lib/provider/native/libnut-screen.class.ts

+4
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ export default class ScreenAction implements ScreenProviderInterface {
3333
screenShot.image,
3434
4,
3535
"grabScreenResult",
36+
screenShot.bitsPerPixel,
37+
screenShot.byteWidth,
3638
ColorMode.BGR,
3739
pixelScaling
3840
)
@@ -63,6 +65,8 @@ export default class ScreenAction implements ScreenProviderInterface {
6365
screenShot.image,
6466
4,
6567
"grabScreenRegionResult",
68+
4,
69+
screenShot.width * 4,
6670
ColorMode.BGR,
6771
pixelScaling
6872
)

0 commit comments

Comments
 (0)