@syngrisi/node-resemble.js 2.1.33-alpha.0 → 2.1.36-alpha.0
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/package.json +2 -2
- package/resemble.js +584 -565
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@syngrisi/node-resemble.js",
|
|
3
|
-
"version": "2.1.
|
|
3
|
+
"version": "2.1.36-alpha.0",
|
|
4
4
|
"description": "Image analysis and comparison for nodejs",
|
|
5
5
|
"main": "resemble.js",
|
|
6
6
|
"scripts": {
|
|
@@ -39,5 +39,5 @@
|
|
|
39
39
|
"gulp-jasmine": "4.0.0",
|
|
40
40
|
"gulp-util": "3.0.7"
|
|
41
41
|
},
|
|
42
|
-
"gitHead": "
|
|
42
|
+
"gitHead": "df73b8517e1c68872f05a655e315524d6eb34eb7"
|
|
43
43
|
}
|
package/resemble.js
CHANGED
|
@@ -12,608 +12,627 @@ var sharp = require('sharp');
|
|
|
12
12
|
//keeping wrong indentation and '_this' for better diff with origin resemble.js
|
|
13
13
|
var _this = {};
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
15
|
+
var pixelTransparency = 1;
|
|
16
|
+
|
|
17
|
+
var errorPixelColor = { // Color for Error Pixels. Between 0 and 255.
|
|
18
|
+
red: 255,
|
|
19
|
+
green: 0,
|
|
20
|
+
blue: 255,
|
|
21
|
+
alpha: 255
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
var errorPixelTransform = {
|
|
25
|
+
flat: function (d1, d2) {
|
|
26
|
+
return {
|
|
27
|
+
r: errorPixelColor.red,
|
|
28
|
+
g: errorPixelColor.green,
|
|
29
|
+
b: errorPixelColor.blue,
|
|
30
|
+
a: errorPixelColor.alpha
|
|
31
|
+
};
|
|
32
|
+
},
|
|
33
|
+
movement: function (d1, d2) {
|
|
34
|
+
return {
|
|
35
|
+
r: ((d2.r * (errorPixelColor.red / 255)) + errorPixelColor.red) / 2,
|
|
36
|
+
g: ((d2.g * (errorPixelColor.green / 255)) + errorPixelColor.green) / 2,
|
|
37
|
+
b: ((d2.b * (errorPixelColor.blue / 255)) + errorPixelColor.blue) / 2,
|
|
38
|
+
a: d2.a
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
var errorPixelTransformer = errorPixelTransform.flat;
|
|
44
|
+
var largeImageThreshold = 1200;
|
|
45
|
+
|
|
46
|
+
_this['resemble'] = function (fileData) {
|
|
47
|
+
|
|
48
|
+
var data = {};
|
|
49
|
+
var images = [];
|
|
50
|
+
var updateCallbackArray = [];
|
|
51
|
+
|
|
52
|
+
var tolerance = { // between 0 and 255
|
|
53
|
+
red: 16,
|
|
54
|
+
green: 16,
|
|
55
|
+
blue: 16,
|
|
56
|
+
alpha: 16,
|
|
57
|
+
minBrightness: 16,
|
|
58
|
+
maxBrightness: 240
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
var ignoreAntialiasing = false;
|
|
62
|
+
var ignoreColors = false;
|
|
63
63
|
var ignoreRectangles = null;
|
|
64
64
|
var includeRectangles = null;
|
|
65
65
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
function loop(x, y, callback){
|
|
77
|
-
var i,j;
|
|
78
|
-
|
|
79
|
-
for (i=0;i<x;i++){
|
|
80
|
-
for (j=0;j<y;j++){
|
|
81
|
-
callback(i, j);
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
function parseImage(sourceImageData, width, height){
|
|
87
|
-
|
|
88
|
-
var pixleCount = 0;
|
|
89
|
-
var redTotal = 0;
|
|
90
|
-
var greenTotal = 0;
|
|
91
|
-
var blueTotal = 0;
|
|
92
|
-
var brightnessTotal = 0;
|
|
93
|
-
|
|
94
|
-
loop(height, width, function(verticalPos, horizontalPos){
|
|
95
|
-
var offset = (verticalPos*width + horizontalPos) * 4;
|
|
96
|
-
var red = sourceImageData[offset];
|
|
97
|
-
var green = sourceImageData[offset + 1];
|
|
98
|
-
var blue = sourceImageData[offset + 2];
|
|
99
|
-
var brightness = getBrightness(red,green,blue);
|
|
100
|
-
|
|
101
|
-
pixleCount++;
|
|
102
|
-
|
|
103
|
-
redTotal += red / 255 * 100;
|
|
104
|
-
greenTotal += green / 255 * 100;
|
|
105
|
-
blueTotal += blue / 255 * 100;
|
|
106
|
-
brightnessTotal += brightness / 255 * 100;
|
|
107
|
-
});
|
|
108
|
-
|
|
109
|
-
data.red = Math.floor(redTotal / pixleCount);
|
|
110
|
-
data.green = Math.floor(greenTotal / pixleCount);
|
|
111
|
-
data.blue = Math.floor(blueTotal / pixleCount);
|
|
112
|
-
data.brightness = Math.floor(brightnessTotal / pixleCount);
|
|
113
|
-
|
|
114
|
-
triggerDataUpdate();
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
function loadImageData( fileData, callback ){
|
|
118
|
-
sharp(fileData)
|
|
119
|
-
.png()
|
|
120
|
-
.toBuffer()
|
|
121
|
-
.then(pngData => {
|
|
122
|
-
var png = new PNG();
|
|
123
|
-
png.parse(pngData, function (err, data) {
|
|
124
|
-
callback(data, data.width, data.height);
|
|
125
|
-
});
|
|
126
|
-
})
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
function isColorSimilar(a, b, color){
|
|
130
|
-
|
|
131
|
-
var absDiff = Math.abs(a - b);
|
|
132
|
-
|
|
133
|
-
if(typeof a === 'undefined'){
|
|
134
|
-
return false;
|
|
135
|
-
}
|
|
136
|
-
if(typeof b === 'undefined'){
|
|
137
|
-
return false;
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
if(a === b){
|
|
141
|
-
return true;
|
|
142
|
-
} else if ( absDiff < tolerance[color] ) {
|
|
143
|
-
return true;
|
|
144
|
-
} else {
|
|
145
|
-
return false;
|
|
146
|
-
}
|
|
147
|
-
}
|
|
66
|
+
function triggerDataUpdate() {
|
|
67
|
+
var len = updateCallbackArray.length;
|
|
68
|
+
var i;
|
|
69
|
+
for (i = 0; i < len; i++) {
|
|
70
|
+
if (typeof updateCallbackArray[i] === 'function') {
|
|
71
|
+
updateCallbackArray[i](data);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
148
75
|
|
|
149
|
-
function
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
(
|
|
76
|
+
function loop(x, y, callback) {
|
|
77
|
+
var i,
|
|
78
|
+
j;
|
|
79
|
+
|
|
80
|
+
for (i = 0; i < x; i++) {
|
|
81
|
+
for (j = 0; j < y; j++) {
|
|
82
|
+
callback(i, j);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
154
85
|
}
|
|
155
86
|
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
function isRGBSimilar(d1, d2){
|
|
178
|
-
var red = isColorSimilar(d1.r,d2.r,'red');
|
|
179
|
-
var green = isColorSimilar(d1.g,d2.g,'green');
|
|
180
|
-
var blue = isColorSimilar(d1.b,d2.b,'blue');
|
|
181
|
-
var alpha = isColorSimilar(d1.a, d2.a, 'alpha');
|
|
182
|
-
|
|
183
|
-
return red && green && blue && alpha;
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
function isContrasting(d1, d2){
|
|
187
|
-
return Math.abs(d1.brightness - d2.brightness) > tolerance.maxBrightness;
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
function getHue(r,g,b){
|
|
191
|
-
|
|
192
|
-
r = r / 255;
|
|
193
|
-
g = g / 255;
|
|
194
|
-
b = b / 255;
|
|
195
|
-
var max = Math.max(r, g, b), min = Math.min(r, g, b);
|
|
196
|
-
var h;
|
|
197
|
-
var d;
|
|
198
|
-
|
|
199
|
-
if (max == min){
|
|
200
|
-
h = 0; // achromatic
|
|
201
|
-
} else{
|
|
202
|
-
d = max - min;
|
|
203
|
-
switch(max){
|
|
204
|
-
case r: h = (g - b) / d + (g < b ? 6 : 0); break;
|
|
205
|
-
case g: h = (b - r) / d + 2; break;
|
|
206
|
-
case b: h = (r - g) / d + 4; break;
|
|
207
|
-
}
|
|
208
|
-
h /= 6;
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
return h;
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
function isAntialiased(sourcePix, data, cacheSet, verticalPos, horizontalPos, width){
|
|
215
|
-
var offset;
|
|
216
|
-
var targetPix;
|
|
217
|
-
var distance = 1;
|
|
218
|
-
var i;
|
|
219
|
-
var j;
|
|
220
|
-
var hasHighContrastSibling = 0;
|
|
221
|
-
var hasSiblingWithDifferentHue = 0;
|
|
222
|
-
var hasEquivilantSibling = 0;
|
|
223
|
-
|
|
224
|
-
addHueInfo(sourcePix);
|
|
225
|
-
|
|
226
|
-
for (i = distance*-1; i <= distance; i++){
|
|
227
|
-
for (j = distance*-1; j <= distance; j++){
|
|
228
|
-
|
|
229
|
-
if(i===0 && j===0){
|
|
230
|
-
// ignore source pixel
|
|
231
|
-
} else {
|
|
232
|
-
|
|
233
|
-
offset = ((verticalPos+j)*width + (horizontalPos+i)) * 4;
|
|
234
|
-
targetPix = getPixelInfo(data, offset, cacheSet);
|
|
235
|
-
|
|
236
|
-
if(targetPix === null){
|
|
237
|
-
continue;
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
addBrightnessInfo(targetPix);
|
|
241
|
-
addHueInfo(targetPix);
|
|
242
|
-
|
|
243
|
-
if( isContrasting(sourcePix, targetPix) ){
|
|
244
|
-
hasHighContrastSibling++;
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
if( isRGBSame(sourcePix,targetPix) ){
|
|
248
|
-
hasEquivilantSibling++;
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
if( Math.abs(targetPix.h - sourcePix.h) > 0.3 ){
|
|
252
|
-
hasSiblingWithDifferentHue++;
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
if( hasSiblingWithDifferentHue > 1 || hasHighContrastSibling > 1){
|
|
256
|
-
return true;
|
|
257
|
-
}
|
|
258
|
-
}
|
|
259
|
-
}
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
if(hasEquivilantSibling < 2){
|
|
263
|
-
return true;
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
return false;
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
function errorPixel(px, offset, data1, data2){
|
|
270
|
-
var data = errorPixelTransformer(data1, data2);
|
|
271
|
-
px[offset] = data.r;
|
|
272
|
-
px[offset + 1] = data.g;
|
|
273
|
-
px[offset + 2] = data.b;
|
|
274
|
-
px[offset + 3] = data.a;
|
|
275
|
-
}
|
|
276
|
-
|
|
277
|
-
function copyPixel(px, offset, data){
|
|
278
|
-
px[offset] = data.r; //r
|
|
279
|
-
px[offset + 1] = data.g; //g
|
|
280
|
-
px[offset + 2] = data.b; //b
|
|
281
|
-
px[offset + 3] = data.a * pixelTransparency; //a
|
|
282
|
-
}
|
|
283
|
-
|
|
284
|
-
function copyGrayScalePixel(px, offset, data){
|
|
285
|
-
px[offset] = data.brightness; //r
|
|
286
|
-
px[offset + 1] = data.brightness; //g
|
|
287
|
-
px[offset + 2] = data.brightness; //b
|
|
288
|
-
px[offset + 3] = data.a * pixelTransparency; //a
|
|
289
|
-
}
|
|
290
|
-
|
|
291
|
-
function getPixelInfo(data, offset, cacheSet){
|
|
292
|
-
var r;
|
|
293
|
-
var g;
|
|
294
|
-
var b;
|
|
295
|
-
var d;
|
|
296
|
-
var a;
|
|
297
|
-
|
|
298
|
-
r = data[offset];
|
|
299
|
-
|
|
300
|
-
if(typeof r !== 'undefined'){
|
|
301
|
-
g = data[offset+1];
|
|
302
|
-
b = data[offset+2];
|
|
303
|
-
a = data[offset+3];
|
|
304
|
-
d = {
|
|
305
|
-
r: r,
|
|
306
|
-
g: g,
|
|
307
|
-
b: b,
|
|
308
|
-
a: a
|
|
309
|
-
};
|
|
310
|
-
|
|
311
|
-
return d;
|
|
312
|
-
} else {
|
|
313
|
-
return null;
|
|
314
|
-
}
|
|
315
|
-
}
|
|
316
|
-
|
|
317
|
-
function addBrightnessInfo(data){
|
|
318
|
-
data.brightness = getBrightness(data.r,data.g,data.b); // 'corrected' lightness
|
|
319
|
-
}
|
|
320
|
-
|
|
321
|
-
function addHueInfo(data){
|
|
322
|
-
data.h = getHue(data.r,data.g,data.b);
|
|
323
|
-
}
|
|
324
|
-
|
|
325
|
-
function analyseImages(img1, img2, width, height){
|
|
326
|
-
|
|
327
|
-
var data1 = img1.data;
|
|
328
|
-
var data2 = img2.data;
|
|
329
|
-
|
|
330
|
-
//TODO
|
|
331
|
-
var imgd = new PNG({
|
|
332
|
-
width: img1.width,
|
|
333
|
-
height: img1.height,
|
|
334
|
-
deflateChunkSize: img1.deflateChunkSize,
|
|
335
|
-
deflateLevel: img1.deflateLevel,
|
|
336
|
-
deflateStrategy: img1.deflateStrategy,
|
|
87
|
+
function parseImage(sourceImageData, width, height) {
|
|
88
|
+
|
|
89
|
+
var pixleCount = 0;
|
|
90
|
+
var redTotal = 0;
|
|
91
|
+
var greenTotal = 0;
|
|
92
|
+
var blueTotal = 0;
|
|
93
|
+
var brightnessTotal = 0;
|
|
94
|
+
|
|
95
|
+
loop(height, width, function (verticalPos, horizontalPos) {
|
|
96
|
+
var offset = (verticalPos * width + horizontalPos) * 4;
|
|
97
|
+
var red = sourceImageData[offset];
|
|
98
|
+
var green = sourceImageData[offset + 1];
|
|
99
|
+
var blue = sourceImageData[offset + 2];
|
|
100
|
+
var brightness = getBrightness(red, green, blue);
|
|
101
|
+
|
|
102
|
+
pixleCount++;
|
|
103
|
+
|
|
104
|
+
redTotal += red / 255 * 100;
|
|
105
|
+
greenTotal += green / 255 * 100;
|
|
106
|
+
blueTotal += blue / 255 * 100;
|
|
107
|
+
brightnessTotal += brightness / 255 * 100;
|
|
337
108
|
});
|
|
338
|
-
var targetPix = imgd.data;
|
|
339
109
|
|
|
340
|
-
|
|
110
|
+
data.red = Math.floor(redTotal / pixleCount);
|
|
111
|
+
data.green = Math.floor(greenTotal / pixleCount);
|
|
112
|
+
data.blue = Math.floor(blueTotal / pixleCount);
|
|
113
|
+
data.brightness = Math.floor(brightnessTotal / pixleCount);
|
|
341
114
|
|
|
342
|
-
|
|
115
|
+
triggerDataUpdate();
|
|
116
|
+
}
|
|
343
117
|
|
|
344
|
-
|
|
118
|
+
function loadImageData(fileData, callback) {
|
|
119
|
+
sharp(fileData)
|
|
120
|
+
.png()
|
|
121
|
+
.toBuffer()
|
|
122
|
+
.then(pngData => {
|
|
123
|
+
var png = new PNG();
|
|
124
|
+
png.parse(pngData, function (err, data) {
|
|
125
|
+
callback(data, data.width, data.height);
|
|
126
|
+
});
|
|
127
|
+
});
|
|
128
|
+
}
|
|
345
129
|
|
|
346
|
-
|
|
347
|
-
var rectagnlesIdx = 0;
|
|
130
|
+
function isColorSimilar(a, b, color) {
|
|
348
131
|
|
|
349
|
-
|
|
350
|
-
skip = 6;
|
|
351
|
-
}
|
|
132
|
+
var absDiff = Math.abs(a - b);
|
|
352
133
|
|
|
353
|
-
|
|
134
|
+
if (typeof a === 'undefined') {
|
|
135
|
+
return false;
|
|
136
|
+
}
|
|
137
|
+
if (typeof b === 'undefined') {
|
|
138
|
+
return false;
|
|
139
|
+
}
|
|
354
140
|
|
|
355
|
-
|
|
141
|
+
if (a === b) {
|
|
142
|
+
return true;
|
|
143
|
+
} else if (absDiff < tolerance[color]) {
|
|
144
|
+
return true;
|
|
145
|
+
} else {
|
|
146
|
+
return false;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
356
149
|
|
|
357
|
-
|
|
358
|
-
|
|
150
|
+
function isWithinRectangle(x, y, rectangle) {
|
|
151
|
+
return (x >= rectangle[1]) &&
|
|
152
|
+
(x < rectangle[1] + rectangle[3]) &&
|
|
153
|
+
(y >= rectangle[0]) &&
|
|
154
|
+
(y < rectangle[0] + rectangle[2]);
|
|
155
|
+
}
|
|
359
156
|
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
g: 0,
|
|
364
|
-
a: 0
|
|
365
|
-
});
|
|
157
|
+
function isNumber(n) {
|
|
158
|
+
return !isNaN(parseFloat(n));
|
|
159
|
+
}
|
|
366
160
|
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
161
|
+
function isPixelBrightnessSimilar(d1, d2) {
|
|
162
|
+
var alpha = isColorSimilar(d1.a, d2.a, 'alpha');
|
|
163
|
+
var brightness = isColorSimilar(d1.brightness, d2.brightness, 'minBrightness');
|
|
164
|
+
return brightness && alpha;
|
|
165
|
+
}
|
|
370
166
|
|
|
371
|
-
|
|
372
|
-
|
|
167
|
+
function getBrightness(r, g, b) {
|
|
168
|
+
return 0.3 * r + 0.59 * g + 0.11 * b;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
function isRGBSame(d1, d2) {
|
|
172
|
+
var red = d1.r === d2.r;
|
|
173
|
+
var green = d1.g === d2.g;
|
|
174
|
+
var blue = d1.b === d2.b;
|
|
175
|
+
return red && green && blue;
|
|
176
|
+
}
|
|
373
177
|
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
178
|
+
function isRGBSimilar(d1, d2) {
|
|
179
|
+
var red = isColorSimilar(d1.r, d2.r, 'red');
|
|
180
|
+
var green = isColorSimilar(d1.g, d2.g, 'green');
|
|
181
|
+
var blue = isColorSimilar(d1.b, d2.b, 'blue');
|
|
182
|
+
var alpha = isColorSimilar(d1.a, d2.a, 'alpha');
|
|
377
183
|
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
184
|
+
return red && green && blue && alpha;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
function isContrasting(d1, d2) {
|
|
188
|
+
return Math.abs(d1.brightness - d2.brightness) > tolerance.maxBrightness;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
function getHue(r, g, b) {
|
|
192
|
+
|
|
193
|
+
r = r / 255;
|
|
194
|
+
g = g / 255;
|
|
195
|
+
b = b / 255;
|
|
196
|
+
var max = Math.max(r, g, b),
|
|
197
|
+
min = Math.min(r, g, b);
|
|
198
|
+
var h;
|
|
199
|
+
var d;
|
|
200
|
+
|
|
201
|
+
if (max == min) {
|
|
202
|
+
h = 0; // achromatic
|
|
203
|
+
} else {
|
|
204
|
+
d = max - min;
|
|
205
|
+
switch (max) {
|
|
206
|
+
case r:
|
|
207
|
+
h = (g - b) / d + (g < b ? 6 : 0);
|
|
208
|
+
break;
|
|
209
|
+
case g:
|
|
210
|
+
h = (b - r) / d + 2;
|
|
211
|
+
break;
|
|
212
|
+
case b:
|
|
213
|
+
h = (r - g) / d + 4;
|
|
214
|
+
break;
|
|
386
215
|
}
|
|
387
|
-
|
|
216
|
+
h /= 6;
|
|
388
217
|
}
|
|
389
218
|
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
219
|
+
return h;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
function isAntialiased(sourcePix, data, cacheSet, verticalPos, horizontalPos, width) {
|
|
223
|
+
var offset;
|
|
224
|
+
var targetPix;
|
|
225
|
+
var distance = 1;
|
|
226
|
+
var i;
|
|
227
|
+
var j;
|
|
228
|
+
var hasHighContrastSibling = 0;
|
|
229
|
+
var hasSiblingWithDifferentHue = 0;
|
|
230
|
+
var hasEquivilantSibling = 0;
|
|
231
|
+
|
|
232
|
+
addHueInfo(sourcePix);
|
|
233
|
+
|
|
234
|
+
for (i = distance * -1; i <= distance; i++) {
|
|
235
|
+
for (j = distance * -1; j <= distance; j++) {
|
|
236
|
+
|
|
237
|
+
if (i === 0 && j === 0) {
|
|
238
|
+
// ignore source pixel
|
|
239
|
+
} else {
|
|
240
|
+
|
|
241
|
+
offset = ((verticalPos + j) * width + (horizontalPos + i)) * 4;
|
|
242
|
+
targetPix = getPixelInfo(data, offset, cacheSet);
|
|
243
|
+
|
|
244
|
+
if (targetPix === null) {
|
|
245
|
+
continue;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
addBrightnessInfo(targetPix);
|
|
249
|
+
addHueInfo(targetPix);
|
|
250
|
+
|
|
251
|
+
if (isContrasting(sourcePix, targetPix)) {
|
|
252
|
+
hasHighContrastSibling++;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
if (isRGBSame(sourcePix, targetPix)) {
|
|
256
|
+
hasEquivilantSibling++;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
if (Math.abs(targetPix.h - sourcePix.h) > 0.3) {
|
|
260
|
+
hasSiblingWithDifferentHue++;
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
if (hasSiblingWithDifferentHue > 1 || hasHighContrastSibling > 1) {
|
|
264
|
+
return true;
|
|
265
|
+
}
|
|
266
|
+
}
|
|
396
267
|
}
|
|
397
|
-
}
|
|
398
|
-
// Better solution but i'm not sure if you want to use reducers in your repo?
|
|
399
|
-
// var isWithinAnyRectangle = includeRectangles.reduce(function (acc, currentRectangle) {
|
|
400
|
-
// if(isWithinRectangle) {
|
|
401
|
-
// return true;
|
|
402
|
-
// }
|
|
403
|
-
// return acc;
|
|
404
|
-
// }, false);
|
|
405
|
-
if(!isWithinAnyRectangle) {
|
|
406
|
-
copyGrayScalePixel(targetPix, offset, pixel2);
|
|
407
|
-
return;
|
|
408
|
-
}
|
|
409
268
|
}
|
|
410
269
|
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
addBrightnessInfo(pixel2);
|
|
415
|
-
|
|
416
|
-
if( isPixelBrightnessSimilar(pixel1, pixel2) ){
|
|
417
|
-
copyGrayScalePixel(targetPix, offset, pixel2);
|
|
418
|
-
} else {
|
|
419
|
-
errorPixel(targetPix, offset, pixel1, pixel2);
|
|
420
|
-
mismatchCount++;
|
|
421
|
-
}
|
|
422
|
-
return;
|
|
423
|
-
}
|
|
424
|
-
|
|
425
|
-
if( isRGBSimilar(pixel1, pixel2) ){
|
|
426
|
-
copyPixel(targetPix, offset, pixel1);
|
|
427
|
-
|
|
428
|
-
} else if( ignoreAntialiasing && (
|
|
429
|
-
addBrightnessInfo(pixel1), // jit pixel info augmentation looks a little weird, sorry.
|
|
430
|
-
addBrightnessInfo(pixel2),
|
|
431
|
-
isAntialiased(pixel1, data1, 1, verticalPos, horizontalPos, width) ||
|
|
432
|
-
isAntialiased(pixel2, data2, 2, verticalPos, horizontalPos, width)
|
|
433
|
-
)){
|
|
434
|
-
|
|
435
|
-
if( isPixelBrightnessSimilar(pixel1, pixel2) ){
|
|
436
|
-
copyGrayScalePixel(targetPix, offset, pixel2);
|
|
437
|
-
} else {
|
|
438
|
-
errorPixel(targetPix, offset, pixel1, pixel2);
|
|
439
|
-
mismatchCount++;
|
|
440
|
-
}
|
|
441
|
-
} else {
|
|
442
|
-
errorPixel(targetPix, offset, pixel1, pixel2);
|
|
443
|
-
mismatchCount++;
|
|
444
|
-
}
|
|
445
|
-
|
|
446
|
-
});
|
|
447
|
-
|
|
448
|
-
data.rawMisMatchPercentage = (mismatchCount / (height*width) * 100);
|
|
449
|
-
data.misMatchPercentage = data.rawMisMatchPercentage.toFixed(2);
|
|
450
|
-
data.analysisTime = Date.now() - time;
|
|
451
|
-
|
|
452
|
-
data.getDiffImage = function(text){
|
|
453
|
-
return imgd;
|
|
454
|
-
};
|
|
455
|
-
|
|
456
|
-
data.getDiffImageAsJPEG = function(quality) {
|
|
457
|
-
return jpeg.encode({
|
|
458
|
-
data: targetPix,
|
|
459
|
-
width: img1.width,
|
|
460
|
-
height: img1.height
|
|
461
|
-
}, quality !== undefined ? quality : 50).data;
|
|
462
|
-
};
|
|
463
|
-
}
|
|
464
|
-
|
|
465
|
-
function compare(one, two){
|
|
466
|
-
|
|
467
|
-
function onceWeHaveBoth(img){
|
|
468
|
-
var width;
|
|
469
|
-
var height;
|
|
470
|
-
|
|
471
|
-
images.push(img);
|
|
472
|
-
if(images.length === 2){
|
|
473
|
-
width = images[0].width > images[1].width ? images[0].width : images[1].width;
|
|
474
|
-
height = images[0].height > images[1].height ? images[0].height : images[1].height;
|
|
475
|
-
|
|
476
|
-
if( (images[0].width === images[1].width) && (images[0].height === images[1].height) ){
|
|
477
|
-
data.isSameDimensions = true;
|
|
478
|
-
} else {
|
|
479
|
-
data.isSameDimensions = false;
|
|
480
|
-
}
|
|
481
|
-
|
|
482
|
-
data.dimensionDifference = { width: images[0].width - images[1].width, height: images[0].height - images[1].height };
|
|
483
|
-
|
|
484
|
-
//lksv: normalization removed
|
|
485
|
-
analyseImages( images[0], images[1], width, height);
|
|
486
|
-
|
|
487
|
-
triggerDataUpdate();
|
|
488
|
-
}
|
|
489
|
-
}
|
|
490
|
-
|
|
491
|
-
images = [];
|
|
492
|
-
loadImageData(one, onceWeHaveBoth);
|
|
493
|
-
loadImageData(two, onceWeHaveBoth);
|
|
494
|
-
}
|
|
495
|
-
|
|
496
|
-
function getCompareApi(param){
|
|
497
|
-
|
|
498
|
-
var secondFileData,
|
|
499
|
-
hasMethod = typeof param === 'function';
|
|
500
|
-
|
|
501
|
-
if( !hasMethod ){
|
|
502
|
-
// assume it's file data
|
|
503
|
-
secondFileData = param;
|
|
504
|
-
}
|
|
505
|
-
|
|
506
|
-
var self = {
|
|
507
|
-
ignoreNothing: function(){
|
|
508
|
-
|
|
509
|
-
tolerance.red = 16;
|
|
510
|
-
tolerance.green = 16;
|
|
511
|
-
tolerance.blue = 16;
|
|
512
|
-
tolerance.alpha = 16;
|
|
513
|
-
tolerance.minBrightness = 16;
|
|
514
|
-
tolerance.maxBrightness = 240;
|
|
515
|
-
|
|
516
|
-
ignoreAntialiasing = false;
|
|
517
|
-
ignoreColors = false;
|
|
518
|
-
|
|
519
|
-
if(hasMethod) { param(); }
|
|
520
|
-
return self;
|
|
521
|
-
},
|
|
522
|
-
ignoreAntialiasing: function(){
|
|
523
|
-
|
|
524
|
-
tolerance.red = 32;
|
|
525
|
-
tolerance.green = 32;
|
|
526
|
-
tolerance.blue = 32;
|
|
527
|
-
tolerance.alpha = 32;
|
|
528
|
-
tolerance.minBrightness = 64;
|
|
529
|
-
tolerance.maxBrightness = 96;
|
|
530
|
-
|
|
531
|
-
ignoreAntialiasing = true;
|
|
532
|
-
ignoreColors = false;
|
|
533
|
-
|
|
534
|
-
if(hasMethod) { param(); }
|
|
535
|
-
return self;
|
|
536
|
-
},
|
|
537
|
-
ignoreColors: function(){
|
|
538
|
-
|
|
539
|
-
tolerance.alpha = 16;
|
|
540
|
-
tolerance.minBrightness = 16;
|
|
541
|
-
tolerance.maxBrightness = 240;
|
|
542
|
-
|
|
543
|
-
ignoreAntialiasing = false;
|
|
544
|
-
ignoreColors = true;
|
|
545
|
-
|
|
546
|
-
if(hasMethod) { param(); }
|
|
547
|
-
return self;
|
|
548
|
-
},
|
|
549
|
-
//array of rectangles, each rectangle is defined as (x, y, width. height)
|
|
550
|
-
//e.g. [[325, 170, 100, 40]]
|
|
551
|
-
ignoreRectangles: function(rectangles) {
|
|
552
|
-
ignoreRectangles = rectangles;
|
|
553
|
-
return self;
|
|
554
|
-
},
|
|
555
|
-
//array of rectangles, each rectangle is defined as (x, y, width. height)
|
|
556
|
-
//e.g. [[325, 170, 100, 40]]
|
|
557
|
-
includeRectangles: function(rectangles) {
|
|
558
|
-
includeRectangles = rectangles;
|
|
559
|
-
return self;
|
|
560
|
-
},
|
|
561
|
-
repaint: function(){
|
|
562
|
-
if(hasMethod) { param(); }
|
|
563
|
-
return self;
|
|
564
|
-
},
|
|
565
|
-
onComplete: function( callback ){
|
|
270
|
+
if (hasEquivilantSibling < 2) {
|
|
271
|
+
return true;
|
|
272
|
+
}
|
|
566
273
|
|
|
567
|
-
|
|
274
|
+
return false;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
function errorPixel(px, offset, data1, data2) {
|
|
278
|
+
var data = errorPixelTransformer(data1, data2);
|
|
279
|
+
px[offset] = data.r;
|
|
280
|
+
px[offset + 1] = data.g;
|
|
281
|
+
px[offset + 2] = data.b;
|
|
282
|
+
px[offset + 3] = data.a;
|
|
283
|
+
}
|
|
568
284
|
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
285
|
+
function copyPixel(px, offset, data) {
|
|
286
|
+
px[offset] = data.r; //r
|
|
287
|
+
px[offset + 1] = data.g; //g
|
|
288
|
+
px[offset + 2] = data.b; //b
|
|
289
|
+
px[offset + 3] = data.a * pixelTransparency; //a
|
|
290
|
+
}
|
|
572
291
|
|
|
573
|
-
|
|
292
|
+
function copyGrayScalePixel(px, offset, data) {
|
|
293
|
+
px[offset] = data.brightness; //r
|
|
294
|
+
px[offset + 1] = data.brightness; //g
|
|
295
|
+
px[offset + 2] = data.brightness; //b
|
|
296
|
+
px[offset + 3] = data.a * pixelTransparency; //a
|
|
297
|
+
}
|
|
574
298
|
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
299
|
+
function getPixelInfo(data, offset, cacheSet) {
|
|
300
|
+
var r;
|
|
301
|
+
var g;
|
|
302
|
+
var b;
|
|
303
|
+
var d;
|
|
304
|
+
var a;
|
|
305
|
+
|
|
306
|
+
r = data[offset];
|
|
307
|
+
|
|
308
|
+
if (typeof r !== 'undefined') {
|
|
309
|
+
g = data[offset + 1];
|
|
310
|
+
b = data[offset + 2];
|
|
311
|
+
a = data[offset + 3];
|
|
312
|
+
d = {
|
|
313
|
+
r: r,
|
|
314
|
+
g: g,
|
|
315
|
+
b: b,
|
|
316
|
+
a: a
|
|
317
|
+
};
|
|
318
|
+
|
|
319
|
+
return d;
|
|
320
|
+
} else {
|
|
321
|
+
return null;
|
|
322
|
+
}
|
|
323
|
+
}
|
|
578
324
|
|
|
579
|
-
|
|
580
|
-
|
|
325
|
+
function addBrightnessInfo(data) {
|
|
326
|
+
data.brightness = getBrightness(data.r, data.g, data.b); // 'corrected' lightness
|
|
327
|
+
}
|
|
581
328
|
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
loadImageData(fileData, function(imageData, width, height){
|
|
586
|
-
parseImage(imageData.data, width, height);
|
|
587
|
-
});
|
|
588
|
-
},
|
|
589
|
-
compareTo: function(secondFileData){
|
|
590
|
-
return getCompareApi(secondFileData);
|
|
591
|
-
}
|
|
592
|
-
};
|
|
329
|
+
function addHueInfo(data) {
|
|
330
|
+
data.h = getHue(data.r, data.g, data.b);
|
|
331
|
+
}
|
|
593
332
|
|
|
594
|
-
|
|
333
|
+
function analyseImages(img1, img2, width, height) {
|
|
595
334
|
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
var undefined;
|
|
335
|
+
var data1 = img1.data;
|
|
336
|
+
var data2 = img2.data;
|
|
599
337
|
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
338
|
+
//TODO
|
|
339
|
+
var imgd = new PNG({
|
|
340
|
+
width: img1.width,
|
|
341
|
+
height: img1.height,
|
|
342
|
+
deflateChunkSize: img1.deflateChunkSize,
|
|
343
|
+
deflateLevel: img1.deflateLevel,
|
|
344
|
+
deflateStrategy: img1.deflateStrategy,
|
|
345
|
+
});
|
|
346
|
+
var targetPix = imgd.data;
|
|
605
347
|
|
|
606
|
-
|
|
607
|
-
errorPixelTransformer = errorPixelTransform[options.errorType];
|
|
608
|
-
}
|
|
348
|
+
var mismatchCount = 0;
|
|
609
349
|
|
|
610
|
-
|
|
350
|
+
var time = Date.now();
|
|
611
351
|
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
352
|
+
var skip;
|
|
353
|
+
|
|
354
|
+
var currentRectangle = null;
|
|
355
|
+
var rectagnlesIdx = 0;
|
|
356
|
+
|
|
357
|
+
if (!!largeImageThreshold && ignoreAntialiasing && (width > largeImageThreshold || height > largeImageThreshold)) {
|
|
358
|
+
skip = 6;
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
loop(height, width, function (verticalPos, horizontalPos) {
|
|
362
|
+
|
|
363
|
+
var offset = (verticalPos * width + horizontalPos) * 4;
|
|
364
|
+
|
|
365
|
+
if (skip) { // only skip if the image isn't small
|
|
366
|
+
if (verticalPos % skip === 0 || horizontalPos % skip === 0) {
|
|
367
|
+
|
|
368
|
+
copyPixel(targetPix, offset, {
|
|
369
|
+
r: 0,
|
|
370
|
+
b: 0,
|
|
371
|
+
g: 0,
|
|
372
|
+
a: 0
|
|
373
|
+
});
|
|
374
|
+
|
|
375
|
+
return;
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
var pixel1 = getPixelInfo(data1, offset, 1);
|
|
380
|
+
var pixel2 = getPixelInfo(data2, offset, 2);
|
|
381
|
+
|
|
382
|
+
if (pixel1 === null || pixel2 === null) {
|
|
383
|
+
return;
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
if (ignoreRectangles) {
|
|
387
|
+
for (rectagnlesIdx = 0; rectagnlesIdx < ignoreRectangles.length; rectagnlesIdx++) {
|
|
388
|
+
currentRectangle = ignoreRectangles[rectagnlesIdx];
|
|
389
|
+
//console.log(currentRectangle, verticalPos, horizontalPos);
|
|
390
|
+
if (isWithinRectangle(verticalPos, horizontalPos, currentRectangle)) {
|
|
391
|
+
copyGrayScalePixel(targetPix, offset, pixel2);
|
|
392
|
+
//copyPixel(targetPix, offset, pixel1, pixel2);
|
|
393
|
+
return;
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
if (includeRectangles) {
|
|
399
|
+
var isWithinAnyRectangle = false;
|
|
400
|
+
for (rectagnlesIdx = 0; rectagnlesIdx < includeRectangles.length; rectagnlesIdx++) {
|
|
401
|
+
currentRectangle = includeRectangles[rectagnlesIdx];
|
|
402
|
+
if (isWithinRectangle(verticalPos, horizontalPos, currentRectangle)) {
|
|
403
|
+
isWithinAnyRectangle = true;
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
// Better solution but i'm not sure if you want to use reducers in your repo?
|
|
407
|
+
// var isWithinAnyRectangle = includeRectangles.reduce(function (acc, currentRectangle) {
|
|
408
|
+
// if(isWithinRectangle) {
|
|
409
|
+
// return true;
|
|
410
|
+
// }
|
|
411
|
+
// return acc;
|
|
412
|
+
// }, false);
|
|
413
|
+
if (!isWithinAnyRectangle) {
|
|
414
|
+
copyGrayScalePixel(targetPix, offset, pixel2);
|
|
415
|
+
return;
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
if (ignoreColors) {
|
|
420
|
+
|
|
421
|
+
addBrightnessInfo(pixel1);
|
|
422
|
+
addBrightnessInfo(pixel2);
|
|
423
|
+
|
|
424
|
+
if (isPixelBrightnessSimilar(pixel1, pixel2)) {
|
|
425
|
+
copyGrayScalePixel(targetPix, offset, pixel2);
|
|
426
|
+
} else {
|
|
427
|
+
errorPixel(targetPix, offset, pixel1, pixel2);
|
|
428
|
+
mismatchCount++;
|
|
429
|
+
}
|
|
430
|
+
return;
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
if (isRGBSimilar(pixel1, pixel2)) {
|
|
434
|
+
copyPixel(targetPix, offset, pixel1);
|
|
435
|
+
|
|
436
|
+
} else if (ignoreAntialiasing && (
|
|
437
|
+
addBrightnessInfo(pixel1), // jit pixel info augmentation looks a little weird, sorry.
|
|
438
|
+
addBrightnessInfo(pixel2),
|
|
439
|
+
isAntialiased(pixel1, data1, 1, verticalPos, horizontalPos, width) ||
|
|
440
|
+
isAntialiased(pixel2, data2, 2, verticalPos, horizontalPos, width)
|
|
441
|
+
)) {
|
|
442
|
+
|
|
443
|
+
if (isPixelBrightnessSimilar(pixel1, pixel2)) {
|
|
444
|
+
copyGrayScalePixel(targetPix, offset, pixel2);
|
|
445
|
+
} else {
|
|
446
|
+
errorPixel(targetPix, offset, pixel1, pixel2);
|
|
447
|
+
mismatchCount++;
|
|
448
|
+
}
|
|
449
|
+
} else {
|
|
450
|
+
errorPixel(targetPix, offset, pixel1, pixel2);
|
|
451
|
+
mismatchCount++;
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
});
|
|
455
|
+
|
|
456
|
+
data.rawMisMatchPercentage = (mismatchCount / (height * width) * 100);
|
|
457
|
+
data.misMatchPercentage = data.rawMisMatchPercentage.toFixed(2);
|
|
458
|
+
data.analysisTime = Date.now() - time;
|
|
459
|
+
|
|
460
|
+
data.getDiffImage = function (text) {
|
|
461
|
+
return imgd;
|
|
462
|
+
};
|
|
463
|
+
|
|
464
|
+
data.getDiffImageAsJPEG = function (quality) {
|
|
465
|
+
return jpeg.encode({
|
|
466
|
+
data: targetPix,
|
|
467
|
+
width: img1.width,
|
|
468
|
+
height: img1.height
|
|
469
|
+
}, quality !== undefined ? quality : 50).data;
|
|
470
|
+
};
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
function compare(one, two) {
|
|
474
|
+
|
|
475
|
+
function onceWeHaveBoth(img) {
|
|
476
|
+
var width;
|
|
477
|
+
var height;
|
|
478
|
+
|
|
479
|
+
images.push(img);
|
|
480
|
+
if (images.length === 2) {
|
|
481
|
+
width = images[0].width > images[1].width ? images[0].width : images[1].width;
|
|
482
|
+
height = images[0].height > images[1].height ? images[0].height : images[1].height;
|
|
483
|
+
|
|
484
|
+
if ((images[0].width === images[1].width) && (images[0].height === images[1].height)) {
|
|
485
|
+
data.isSameDimensions = true;
|
|
486
|
+
} else {
|
|
487
|
+
data.isSameDimensions = false;
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
data.dimensionDifference = {
|
|
491
|
+
width: images[0].width - images[1].width,
|
|
492
|
+
height: images[0].height - images[1].height
|
|
493
|
+
};
|
|
494
|
+
|
|
495
|
+
//lksv: normalization removed
|
|
496
|
+
analyseImages(images[0], images[1], width, height);
|
|
497
|
+
|
|
498
|
+
triggerDataUpdate();
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
images = [];
|
|
503
|
+
loadImageData(one, onceWeHaveBoth);
|
|
504
|
+
loadImageData(two, onceWeHaveBoth);
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
function getCompareApi(param) {
|
|
508
|
+
|
|
509
|
+
var secondFileData,
|
|
510
|
+
hasMethod = typeof param === 'function';
|
|
511
|
+
|
|
512
|
+
if (!hasMethod) {
|
|
513
|
+
// assume it's file data
|
|
514
|
+
secondFileData = param;
|
|
515
|
+
}
|
|
516
|
+
|
|
517
|
+
var self = {
|
|
518
|
+
ignoreNothing: function () {
|
|
519
|
+
|
|
520
|
+
tolerance.red = 16;
|
|
521
|
+
tolerance.green = 16;
|
|
522
|
+
tolerance.blue = 16;
|
|
523
|
+
tolerance.alpha = 16;
|
|
524
|
+
tolerance.minBrightness = 16;
|
|
525
|
+
tolerance.maxBrightness = 240;
|
|
526
|
+
|
|
527
|
+
ignoreAntialiasing = false;
|
|
528
|
+
ignoreColors = false;
|
|
529
|
+
|
|
530
|
+
if (hasMethod) {
|
|
531
|
+
param();
|
|
532
|
+
}
|
|
533
|
+
return self;
|
|
534
|
+
},
|
|
535
|
+
ignoreAntialiasing: function () {
|
|
536
|
+
|
|
537
|
+
tolerance.red = 32;
|
|
538
|
+
tolerance.green = 32;
|
|
539
|
+
tolerance.blue = 32;
|
|
540
|
+
tolerance.alpha = 32;
|
|
541
|
+
tolerance.minBrightness = 64;
|
|
542
|
+
tolerance.maxBrightness = 96;
|
|
543
|
+
|
|
544
|
+
ignoreAntialiasing = true;
|
|
545
|
+
ignoreColors = false;
|
|
546
|
+
|
|
547
|
+
if (hasMethod) {
|
|
548
|
+
param();
|
|
549
|
+
}
|
|
550
|
+
return self;
|
|
551
|
+
},
|
|
552
|
+
ignoreColors: function () {
|
|
553
|
+
|
|
554
|
+
tolerance.alpha = 16;
|
|
555
|
+
tolerance.minBrightness = 16;
|
|
556
|
+
tolerance.maxBrightness = 240;
|
|
557
|
+
|
|
558
|
+
ignoreAntialiasing = false;
|
|
559
|
+
ignoreColors = true;
|
|
560
|
+
|
|
561
|
+
if (hasMethod) {
|
|
562
|
+
param();
|
|
563
|
+
}
|
|
564
|
+
return self;
|
|
565
|
+
},
|
|
566
|
+
//array of rectangles, each rectangle is defined as (x, y, width. height)
|
|
567
|
+
//e.g. [[325, 170, 100, 40]]
|
|
568
|
+
ignoreRectangles: function (rectangles) {
|
|
569
|
+
ignoreRectangles = rectangles;
|
|
570
|
+
return self;
|
|
571
|
+
},
|
|
572
|
+
//array of rectangles, each rectangle is defined as (x, y, width. height)
|
|
573
|
+
//e.g. [[325, 170, 100, 40]]
|
|
574
|
+
includeRectangles: function (rectangles) {
|
|
575
|
+
includeRectangles = rectangles;
|
|
576
|
+
return self;
|
|
577
|
+
},
|
|
578
|
+
repaint: function () {
|
|
579
|
+
if (hasMethod) {
|
|
580
|
+
param();
|
|
581
|
+
}
|
|
582
|
+
return self;
|
|
583
|
+
},
|
|
584
|
+
onComplete: function (callback) {
|
|
585
|
+
|
|
586
|
+
updateCallbackArray.push(callback);
|
|
587
|
+
|
|
588
|
+
var wrapper = function () {
|
|
589
|
+
compare(fileData, secondFileData);
|
|
590
|
+
};
|
|
591
|
+
|
|
592
|
+
wrapper();
|
|
593
|
+
|
|
594
|
+
return getCompareApi(wrapper);
|
|
595
|
+
}
|
|
596
|
+
};
|
|
597
|
+
|
|
598
|
+
return self;
|
|
599
|
+
}
|
|
600
|
+
|
|
601
|
+
return {
|
|
602
|
+
onComplete: function (callback) {
|
|
603
|
+
updateCallbackArray.push(callback);
|
|
604
|
+
loadImageData(fileData, function (imageData, width, height) {
|
|
605
|
+
parseImage(imageData.data, width, height);
|
|
606
|
+
});
|
|
607
|
+
},
|
|
608
|
+
compareTo: function (secondFileData) {
|
|
609
|
+
return getCompareApi(secondFileData);
|
|
610
|
+
}
|
|
611
|
+
};
|
|
612
|
+
|
|
613
|
+
};
|
|
614
|
+
|
|
615
|
+
_this['resemble'].outputSettings = function (options) {
|
|
616
|
+
var key;
|
|
617
|
+
var undefined;
|
|
618
|
+
|
|
619
|
+
if (options.errorColor) {
|
|
620
|
+
for (key in options.errorColor) {
|
|
621
|
+
errorPixelColor[key] = options.errorColor[key] === undefined ? errorPixelColor[key] : options.errorColor[key];
|
|
622
|
+
}
|
|
623
|
+
}
|
|
624
|
+
|
|
625
|
+
if (options.errorType && errorPixelTransform[options.errorType]) {
|
|
626
|
+
errorPixelTransformer = errorPixelTransform[options.errorType];
|
|
627
|
+
}
|
|
628
|
+
|
|
629
|
+
pixelTransparency = options.transparency || pixelTransparency;
|
|
630
|
+
|
|
631
|
+
if (options.largeImageThreshold !== undefined) {
|
|
632
|
+
largeImageThreshold = options.largeImageThreshold;
|
|
633
|
+
}
|
|
615
634
|
|
|
616
|
-
|
|
617
|
-
|
|
635
|
+
return this;
|
|
636
|
+
};
|
|
618
637
|
|
|
619
|
-
module.exports = _this['resemble']
|
|
638
|
+
module.exports = _this['resemble'];
|