From 38a2ea8391cc01a0c47d4b8c2c37cd9c58e4693b Mon Sep 17 00:00:00 2001 From: Christoph Burgmer Date: Mon, 9 Jun 2014 19:13:06 +0200 Subject: [PATCH 1/3] Implement alternative interface for tolerance value --- js/imagediff.js | 12 ++++++++--- spec/ImageDiffSpec.js | 48 ++++++++++++++++++++++++++++++------------- 2 files changed, 43 insertions(+), 17 deletions(-) diff --git a/js/imagediff.js b/js/imagediff.js index 958aab6..6808000 100644 --- a/js/imagediff.js +++ b/js/imagediff.js @@ -148,18 +148,24 @@ function equalDimensions (a, b) { return equalHeight(a, b) && equalWidth(a, b); } - function equal (a, b, tolerance) { + function equal (a, b, options) { var aData = a.data, bData = b.data, length = aData.length, + absoluteTolerance = 0, i; - tolerance = tolerance || 0; + if (typeof options === "number") { + // Support old interface + absoluteTolerance = options; + } else if (options) { + absoluteTolerance = (options.tolerance * 256) || 0; + } if (!equalDimensions(a, b)) return false; - for (i = length; i--;) if (aData[i] !== bData[i] && Math.abs(aData[i] - bData[i]) > tolerance) return false; + for (i = length; i--;) if (aData[i] !== bData[i] && Math.abs(aData[i] - bData[i]) > absoluteTolerance) return false; return true; } diff --git a/spec/ImageDiffSpec.js b/spec/ImageDiffSpec.js index 05fea69..e48757c 100644 --- a/spec/ImageDiffSpec.js +++ b/spec/ImageDiffSpec.js @@ -258,22 +258,42 @@ describe('ImageUtils', function() { expect(imagediff.equal(a, b)).toEqual(false); }); - it('should be equal within optional tolerance', function () { - b = context.createImageData(2, 2); - b.data[0] = 100; - expect(imagediff.equal(a, b, 101)).toEqual(true); - }); + describe("tolerance", function () { + it('should be equal within optional tolerance', function () { + b = context.createImageData(2, 2); + b.data[0] = 100; + expect(imagediff.equal(a, b, 101)).toEqual(true); + }); - it('should be equal optional tolerance', function () { - b = context.createImageData(2, 2); - b.data[0] = 100; - expect(imagediff.equal(a, b, 100)).toEqual(true); - }); + it('should be equal optional tolerance', function () { + b = context.createImageData(2, 2); + b.data[0] = 100; + expect(imagediff.equal(a, b, 100)).toEqual(true); + }); - it('should not be equal outside tolerance', function () { - b = context.createImageData(2, 2); - b.data[0] = 100; - expect(imagediff.equal(a, b, 5)).toEqual(false); + it('should not be equal outside tolerance', function () { + b = context.createImageData(2, 2); + b.data[0] = 100; + expect(imagediff.equal(a, b, 5)).toEqual(false); + }); + + it('should be equal within optional tolerance using new API', function () { + b = context.createImageData(2, 2); + b.data[0] = 100; + expect(imagediff.equal(a, b, {tolerance: 101/256})).toEqual(true); + }); + + it('should be equal optional tolerance using new API', function () { + b = context.createImageData(2, 2); + b.data[0] = 100; + expect(imagediff.equal(a, b, {tolerance: 100/256})).toEqual(true); + }); + + it('should not be equal outside tolerance using new API', function () { + b = context.createImageData(2, 2); + b.data[0] = 100; + expect(imagediff.equal(a, b, {tolerance: 5/256})).toEqual(false); + }); }); }); From 488e5e2117236038303ae46c0b897b11ce47a880 Mon Sep 17 00:00:00 2001 From: Christoph Burgmer Date: Mon, 9 Jun 2014 23:04:17 +0200 Subject: [PATCH 2/3] Implement total tolerance --- js/imagediff.js | 32 +++++++++++++++++++++++++------- spec/ImageDiffSpec.js | 18 ++++++++++++++++++ 2 files changed, 43 insertions(+), 7 deletions(-) diff --git a/js/imagediff.js b/js/imagediff.js index 6808000..cf192dd 100644 --- a/js/imagediff.js +++ b/js/imagediff.js @@ -148,26 +148,44 @@ function equalDimensions (a, b) { return equalHeight(a, b) && equalWidth(a, b); } + function hasTotalDifference (aData, bData, absoluteTolerance) { + var length = aData.length, + sumDifferences = 0, + i; + for (i = 0; i < length; i++) { + sumDifferences += Math.abs(aData[i] - bData[i]); + }; + + return sumDifferences / (255 * length) <= (absoluteTolerance / 256); + } + function hasPerPixelDifference (aData, bData, absoluteTolerance) { + var length = aData.length, + i; + for (i = length; i--;) if (aData[i] !== bData[i] && Math.abs(aData[i] - bData[i]) > absoluteTolerance) return false; + return true; + } function equal (a, b, options) { var - aData = a.data, - bData = b.data, - length = aData.length, + aData = a.data, + bData = b.data, absoluteTolerance = 0, - i; + totalTolerance = false; if (typeof options === "number") { // Support old interface absoluteTolerance = options; } else if (options) { absoluteTolerance = (options.tolerance * 256) || 0; + totalTolerance = options.totalTolerance || false; } if (!equalDimensions(a, b)) return false; - for (i = length; i--;) if (aData[i] !== bData[i] && Math.abs(aData[i] - bData[i]) > absoluteTolerance) return false; - - return true; + if (totalTolerance) { + return hasTotalDifference(aData, bData, absoluteTolerance) + } else { + return hasPerPixelDifference(aData, bData, absoluteTolerance); + } } diff --git a/spec/ImageDiffSpec.js b/spec/ImageDiffSpec.js index e48757c..2bc997d 100644 --- a/spec/ImageDiffSpec.js +++ b/spec/ImageDiffSpec.js @@ -294,6 +294,24 @@ describe('ImageUtils', function() { b.data[0] = 100; expect(imagediff.equal(a, b, {tolerance: 5/256})).toEqual(false); }); + + it('should be equal within optional total tolerance', function () { + b = context.createImageData(2, 2); + b.data[0] = 255; + expect(imagediff.equal(a, b, {tolerance: 1/4, totalTolerance: true})).toEqual(true); + }); + + it('should be equal optional total tolerance', function () { + b = context.createImageData(2, 2); + b.data[0] = 255; + expect(imagediff.equal(a, b, {tolerance: 1/16, totalTolerance: true})).toEqual(true); + }); + + it('should not be equal outside total tolerance', function () { + b = context.createImageData(2, 2); + b.data[0] = 255; + expect(imagediff.equal(a, b, {tolerance: 1/20, totalTolerance: true})).toEqual(false); + }); }); }); From 574ef8681da4a2186ad50786eb172c578a05fbdd Mon Sep 17 00:00:00 2001 From: Christoph Burgmer Date: Wed, 11 Jun 2014 19:13:17 +0200 Subject: [PATCH 3/3] Propose better interface for tolerance methods --- js/imagediff.js | 30 ++++++++++++++++-------------- spec/ImageDiffSpec.js | 19 +++++++++++++------ 2 files changed, 29 insertions(+), 20 deletions(-) diff --git a/js/imagediff.js b/js/imagediff.js index cf192dd..c1b12ff 100644 --- a/js/imagediff.js +++ b/js/imagediff.js @@ -148,7 +148,7 @@ function equalDimensions (a, b) { return equalHeight(a, b) && equalWidth(a, b); } - function hasTotalDifference (aData, bData, absoluteTolerance) { + function hasTotalDifference (aData, bData, totalToleranceRatio) { var length = aData.length, sumDifferences = 0, i; @@ -156,12 +156,12 @@ sumDifferences += Math.abs(aData[i] - bData[i]); }; - return sumDifferences / (255 * length) <= (absoluteTolerance / 256); + return sumDifferences / (255 * length) <= totalToleranceRatio; } - function hasPerPixelDifference (aData, bData, absoluteTolerance) { + function hasPerPixelDifference (aData, bData, relativePixelTolerance) { var length = aData.length, i; - for (i = length; i--;) if (aData[i] !== bData[i] && Math.abs(aData[i] - bData[i]) > absoluteTolerance) return false; + for (i = length; i--;) if (aData[i] !== bData[i] && Math.abs(aData[i] - bData[i]) > relativePixelTolerance) return false; return true; } function equal (a, b, options) { @@ -169,22 +169,24 @@ var aData = a.data, bData = b.data, - absoluteTolerance = 0, - totalTolerance = false; + toleranceValue, toleranceMethod; + // Support old interface if (typeof options === "number") { - // Support old interface - absoluteTolerance = options; - } else if (options) { - absoluteTolerance = (options.tolerance * 256) || 0; - totalTolerance = options.totalTolerance || false; + options = { + toleranceValue: options + }; } + toleranceValue = options && options.toleranceValue || 0; + toleranceMethod = options && options.toleranceMethod || 'relativePerPixel'; + if (!equalDimensions(a, b)) return false; - if (totalTolerance) { - return hasTotalDifference(aData, bData, absoluteTolerance) + + if (toleranceMethod === 'totalRatio') { + return hasTotalDifference(aData, bData, toleranceValue) } else { - return hasPerPixelDifference(aData, bData, absoluteTolerance); + return hasPerPixelDifference(aData, bData, toleranceValue); } } diff --git a/spec/ImageDiffSpec.js b/spec/ImageDiffSpec.js index 2bc997d..9e5b900 100644 --- a/spec/ImageDiffSpec.js +++ b/spec/ImageDiffSpec.js @@ -280,37 +280,44 @@ describe('ImageUtils', function() { it('should be equal within optional tolerance using new API', function () { b = context.createImageData(2, 2); b.data[0] = 100; - expect(imagediff.equal(a, b, {tolerance: 101/256})).toEqual(true); + expect(imagediff.equal(a, b, {toleranceValue: 101, toleranceMethod: 'relativePerPixel'})).toEqual(true); }); it('should be equal optional tolerance using new API', function () { b = context.createImageData(2, 2); b.data[0] = 100; - expect(imagediff.equal(a, b, {tolerance: 100/256})).toEqual(true); + expect(imagediff.equal(a, b, {toleranceValue: 100, toleranceMethod: 'relativePerPixel'})).toEqual(true); }); it('should not be equal outside tolerance using new API', function () { b = context.createImageData(2, 2); b.data[0] = 100; - expect(imagediff.equal(a, b, {tolerance: 5/256})).toEqual(false); + expect(imagediff.equal(a, b, {toleranceValue: 5, toleranceMethod: 'relativePerPixel'})).toEqual(false); }); it('should be equal within optional total tolerance', function () { b = context.createImageData(2, 2); b.data[0] = 255; - expect(imagediff.equal(a, b, {tolerance: 1/4, totalTolerance: true})).toEqual(true); + expect(imagediff.equal(a, b, {toleranceValue: 1/4, toleranceMethod: 'totalRatio'})).toEqual(true); }); it('should be equal optional total tolerance', function () { b = context.createImageData(2, 2); b.data[0] = 255; - expect(imagediff.equal(a, b, {tolerance: 1/16, totalTolerance: true})).toEqual(true); + expect(imagediff.equal(a, b, {toleranceValue: 1/16, toleranceMethod: 'totalRatio'})).toEqual(true); }); it('should not be equal outside total tolerance', function () { b = context.createImageData(2, 2); b.data[0] = 255; - expect(imagediff.equal(a, b, {tolerance: 1/20, totalTolerance: true})).toEqual(false); + expect(imagediff.equal(a, b, {toleranceValue: 1/20, toleranceMethod: 'totalRatio'})).toEqual(false); + }); + + it('should use tolerance method "relativePerPixel" by default', function () { + b = context.createImageData(2, 2); + b.data[0] = 100; + expect(imagediff.equal(a, b, {toleranceValue: 100})).toEqual(true); + expect(imagediff.equal(a, b, {toleranceValue: 99})).toEqual(false); }); }); });