Skip to content

Commit 1d2c05d

Browse files
authored
Merge pull request #41 from happo/negative
Return negative colorDiff if pixel is darker
2 parents da33fc3 + 364b3a1 commit 1d2c05d

File tree

6 files changed

+74
-48
lines changed

6 files changed

+74
-48
lines changed

package.json

+8
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,14 @@
2020
"test-ci": "yarn start-server & yarn test",
2121
"test": "jest"
2222
},
23+
"prettier": {
24+
"trailingComma": "all",
25+
"tabWidth": 2,
26+
"semi": true,
27+
"singleQuote": true,
28+
"printWidth": 80,
29+
"arrowParens": "avoid"
30+
},
2331
"dependencies": {
2432
"imagetracerjs": "^1.2.5"
2533
},

src/__tests__/colorDelta-test.js

+31-19
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
const colorDelta = require("../colorDelta");
2-
const { colorDeltaChannels } = require("../colorDelta");
1+
const colorDelta = require('../colorDelta');
2+
const { colorDeltaChannels } = require('../colorDelta');
33

4-
describe("colorDelta", () => {
5-
it("produces the same results as colorDeltaChannels", () => {
4+
describe('colorDelta', () => {
5+
it('produces the same results as colorDeltaChannels', () => {
66
const pixels = [
77
[0, 0, 0, 255],
88
[255, 255, 255, 255],
@@ -23,54 +23,66 @@ describe("colorDelta", () => {
2323
pixels[j][0],
2424
pixels[j][1],
2525
pixels[j][2],
26-
pixels[j][3]
27-
)
26+
pixels[j][3],
27+
),
2828
);
2929
}
3030
}
3131
});
3232
});
3333

34-
it("is large when comparing black and white", () => {
34+
it('is large when comparing black and white', () => {
3535
expect(colorDeltaChannels(0, 0, 0, 255, 255, 255, 255, 255)).toBeGreaterThan(
36-
0.92
36+
0.92,
3737
);
3838
});
3939

40-
it("is small when comparing black and very dark grey", () => {
40+
it('is small when comparing black and very dark grey', () => {
4141
expect(colorDeltaChannels(0, 0, 0, 255, 10, 10, 10, 255)).toBeLessThan(0.02);
4242
});
4343

44-
it("is medium when comparing black and medium grey", () => {
44+
it('is medium when comparing black and medium grey', () => {
4545
const delta = colorDeltaChannels(0, 0, 0, 255, 127, 127, 127, 255);
4646
expect(delta).toBeGreaterThan(0.21);
4747
expect(delta).toBeLessThan(0.24);
4848
});
4949

50-
it("is medium when comparing red and blue", () => {
51-
const delta = colorDeltaChannels(255, 0, 0, 255, 0, 0, 255, 255);
50+
it('is medium when comparing red and blue', () => {
51+
const delta = Math.abs(colorDeltaChannels(255, 0, 0, 255, 0, 0, 255, 255));
5252
expect(delta).toBeGreaterThan(0.5);
5353
expect(delta).toBeLessThan(0.51);
5454
});
5555

56-
it("is one when comparing filler pixel and white", () => {
56+
it('is one when comparing filler pixel and white', () => {
5757
expect(colorDeltaChannels(1, 1, 1, 1, 255, 255, 255, 255)).toEqual(1);
5858
});
5959

60-
it("is large when comparing transparent and black", () => {
61-
expect(colorDeltaChannels(0, 0, 0, 0, 0, 0, 0, 255)).toBeGreaterThan(0.92);
60+
it('is large when comparing transparent and black', () => {
61+
expect(
62+
Math.abs(colorDeltaChannels(0, 0, 0, 0, 0, 0, 0, 255)),
63+
).toBeGreaterThan(0.92);
6264
});
6365

64-
it("is large when comparing white and filler pixel", () => {
66+
it('is large when comparing white and filler pixel', () => {
6567
expect(colorDeltaChannels(255, 255, 255, 255, 1, 1, 1, 1)).toBeGreaterThan(
66-
0.92
68+
0.92,
6769
);
6870
});
6971

70-
it("is one when comparing filler pixel and some other color", () => {
72+
it('is one when comparing filler pixel and some other color', () => {
7173
expect(colorDeltaChannels(1, 1, 1, 1, 33, 33, 33, 10)).toEqual(1);
7274
});
7375

74-
it("is small when comparing transparent and similar color", () => {
76+
it('is small when comparing transparent and similar color', () => {
7577
expect(colorDeltaChannels(1, 46, 250, 0, 1, 42, 250, 4)).toBeLessThan(0.05);
7678
});
79+
80+
it('is negative when comparing white and black', () => {
81+
expect(colorDeltaChannels(255, 255, 255, 255, 0, 0, 0, 255)).toBeLessThan(0);
82+
});
83+
84+
it('is positive when comparing black and white', () => {
85+
expect(colorDeltaChannels(0, 0, 0, 255, 255, 255, 255, 255)).toBeGreaterThan(
86+
0,
87+
);
88+
});

src/__tests__/getDiffPixel-test.js

+11-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,17 @@ let currentPixel;
77
beforeEach(() => {
88
previousPixel = [255, 255, 255, 255];
99
currentPixel = [255, 255, 255, 255];
10-
subject = () => getDiffPixel(previousPixel, currentPixel);
10+
subject = () =>
11+
getDiffPixel(
12+
previousPixel[0],
13+
previousPixel[1],
14+
previousPixel[2],
15+
previousPixel[3],
16+
currentPixel[0],
17+
currentPixel[1],
18+
currentPixel[2],
19+
currentPixel[3],
20+
);
1121
});
1222

1323
it('returns semi-opaque source if no diff', () => {

src/colorDelta.js

+9-3
Original file line numberDiff line numberDiff line change
@@ -56,11 +56,17 @@ function colorDeltaChannels(r1, g1, b1, a1, r2, g2, b2, a2) {
5656
b2 = blend(b2, a2);
5757
}
5858

59-
const y = rgb2y(r1, g1, b1) - rgb2y(r2, g2, b2);
59+
const y1 = rgb2y(r1, g1, b1);
60+
const y2 = rgb2y(r2, g2, b2);
61+
const y = y1 - y2;
6062
const i = rgb2i(r1, g1, b1) - rgb2i(r2, g2, b2);
6163
const q = rgb2q(r1, g1, b1) - rgb2q(r2, g2, b2);
6264

63-
return (0.5053 * y * y + 0.299 * i * i + 0.1957 * q * q) / MAX_YIQ_DIFFERENCE;
65+
const delta =
66+
(0.5053 * y * y + 0.299 * i * i + 0.1957 * q * q) / MAX_YIQ_DIFFERENCE;
67+
68+
// encode whether the pixel lightens or darkens in the sign
69+
return y1 > y2 ? -delta : delta;
6470
}
6571

6672
/**
@@ -83,7 +89,7 @@ function colorDelta(previousPixel, currentPixel) {
8389
currentPixel[0],
8490
currentPixel[1],
8591
currentPixel[2],
86-
currentPixel[3]
92+
currentPixel[3],
8793
);
8894
}
8995

src/createDiffImage.js

+8-12
Original file line numberDiff line numberDiff line change
@@ -22,18 +22,14 @@ module.exports = function createDiffImage({ image1Data, image2Data }) {
2222
// Render image
2323
for (let index = 0; index < width; index += 4) {
2424
const { diff, pixel } = getDiffPixel(
25-
[
26-
image1Data[row][index],
27-
image1Data[row][index + 1],
28-
image1Data[row][index + 2],
29-
image1Data[row][index + 3],
30-
],
31-
[
32-
image2Data[row][index],
33-
image2Data[row][index + 1],
34-
image2Data[row][index + 2],
35-
image2Data[row][index + 3],
36-
],
25+
image1Data[row][index],
26+
image1Data[row][index + 1],
27+
image1Data[row][index + 2],
28+
image1Data[row][index + 3],
29+
image2Data[row][index],
30+
image2Data[row][index + 1],
31+
image2Data[row][index + 2],
32+
image2Data[row][index + 3],
3733
);
3834

3935
totalDiff += diff;

src/getDiffPixel.js

+7-13
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,26 @@
1-
const compose = require('./compose');
2-
const colorDelta = require('./colorDelta');
1+
const compose = require("./compose");
2+
const { colorDeltaChannels } = require("./colorDelta");
33

44
const TRANSPARENT = [0, 0, 0, 0];
55

6-
module.exports = function getDiffPixel(previousPixel, currentPixel) {
6+
module.exports = function getDiffPixel(r1, g1, b1, a1, r2, g2, b2, a2) {
77
// Compute a score that represents the difference between 2 pixels
8-
const diff = colorDelta(previousPixel, currentPixel);
8+
const diff = Math.abs(colorDeltaChannels(r1, g1, b1, a1, r2, g2, b2, a2));
99
if (diff === 0) {
10-
if (currentPixel[3] === 0) {
10+
if (a2 === 0) {
1111
return {
1212
diff,
1313
pixel: TRANSPARENT,
1414
};
1515
}
1616
return {
1717
diff,
18-
pixel: compose(
19-
[currentPixel[0], currentPixel[1], currentPixel[2], 140],
20-
TRANSPARENT,
21-
),
18+
pixel: compose([r2, g2, b2, 140], TRANSPARENT),
2219
};
2320
}
2421

2522
return {
2623
diff,
27-
pixel: compose(
28-
[179, 54, 130, 255 * Math.max(0.2, diff)],
29-
TRANSPARENT,
30-
),
24+
pixel: compose([179, 54, 130, 255 * Math.max(0.2, diff)], TRANSPARENT),
3125
};
3226
};

0 commit comments

Comments
 (0)