New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

blink-diff

Package Overview
Dependencies
Maintainers
2
Versions
13
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

blink-diff - npm Package Compare versions

Comparing version 1.0.7 to 1.0.8

.editorconfig

6

CHANGELOG.md

@@ -1,4 +0,8 @@

Changelog
CHANGELOG
=========
v1.0.8 - 03/29/15
* Cleanup
* Added code-Climate, coveralls, and others
v1.0.7 - 12/06/14

@@ -5,0 +9,0 @@ * Block-out areas + color definition

1440

index.js

@@ -1,7 +0,7 @@

// Copyright 2014 Yahoo! Inc.
// Copyright 2014-2015 Yahoo! Inc.
// Copyrights licensed under the Mit License. See the accompanying LICENSE file for terms.
var assert = require('assert'),
PNGImage = require('pngjs-image'),
Promise = require('promise');
PNGImage = require('pngjs-image'),
Promise = require('promise');

@@ -131,86 +131,86 @@ /**

this._imageA = options.imageA;
this._imageAPath = options.imageAPath;
assert.ok(options.imageAPath || options.imageA, "Path to image A not given.");
this._imageA = options.imageA;
this._imageAPath = options.imageAPath;
assert.ok(options.imageAPath || options.imageA, "Image A not given.");
this._imageB = options.imageB;
this._imageBPath = options.imageBPath;
assert.ok(options.imageBPath || options.imageB, "Path to image B not given.");
this._imageB = options.imageB;
this._imageBPath = options.imageBPath;
assert.ok(options.imageBPath || options.imageB, "Image B not given.");
this._imageOutput = null;
this._imageOutputPath = options.imageOutputPath;
this._imageOutputLimit = options.imageOutputLimit || BlinkDiff.OUTPUT_ALL;
this._imageOutput = null;
this._imageOutputPath = options.imageOutputPath;
this._imageOutputLimit = options.imageOutputLimit || BlinkDiff.OUTPUT_ALL;
// Pixel or Percent
this._thresholdType = options.thresholdType || BlinkDiff.THRESHOLD_PIXEL;
// Pixel or Percent
this._thresholdType = options.thresholdType || BlinkDiff.THRESHOLD_PIXEL;
// How many pixels different to ignore.
this._threshold = options.threshold || 500;
// How many pixels different to ignore.
this._threshold = options.threshold || 500;
this._delta = options.delta || 20;
this._delta = options.delta || 20;
this._outputMaskRed = options.outputMaskRed || 255;
this._outputMaskGreen = options.outputMaskGreen || 0;
this._outputMaskBlue = options.outputMaskBlue || 0;
this._outputMaskAlpha = options.outputMaskAlpha || 255;
this._outputMaskOpacity = options.outputMaskOpacity || 0.7;
this._outputMaskRed = options.outputMaskRed || 255;
this._outputMaskGreen = options.outputMaskGreen || 0;
this._outputMaskBlue = options.outputMaskBlue || 0;
this._outputMaskAlpha = options.outputMaskAlpha || 255;
this._outputMaskOpacity = options.outputMaskOpacity || 0.7;
this._outputBackgroundRed = options.outputBackgroundRed || 0;
this._outputBackgroundGreen = options.outputBackgroundGreen || 0;
this._outputBackgroundBlue = options.outputBackgroundBlue || 0;
this._outputBackgroundAlpha = options.outputBackgroundAlpha;
this._outputBackgroundOpacity = options.outputBackgroundOpacity || 0.6;
this._outputBackgroundRed = options.outputBackgroundRed || 0;
this._outputBackgroundGreen = options.outputBackgroundGreen || 0;
this._outputBackgroundBlue = options.outputBackgroundBlue || 0;
this._outputBackgroundAlpha = options.outputBackgroundAlpha;
this._outputBackgroundOpacity = options.outputBackgroundOpacity || 0.6;
if (options.hideShift) {
this._outputShiftRed = this._outputBackgroundRed;
this._outputShiftGreen = this._outputBackgroundGreen;
this._outputShiftBlue = this._outputBackgroundBlue;
this._outputShiftAlpha = this._outputBackgroundAlpha;
this._outputShiftOpacity = this._outputBackgroundOpacity;
if (options.hideShift) {
this._outputShiftRed = this._outputBackgroundRed;
this._outputShiftGreen = this._outputBackgroundGreen;
this._outputShiftBlue = this._outputBackgroundBlue;
this._outputShiftAlpha = this._outputBackgroundAlpha;
this._outputShiftOpacity = this._outputBackgroundOpacity;
} else {
this._outputShiftRed = options.outputShiftRed || 200;
this._outputShiftGreen = options.outputShiftGreen || 100;
this._outputShiftBlue = options.outputShiftBlue || 0;
this._outputShiftAlpha = options.outputShiftAlpha || 255;
this._outputShiftOpacity = options.outputShiftOpacity || 0.7;
}
} else {
this._outputShiftRed = options.outputShiftRed || 200;
this._outputShiftGreen = options.outputShiftGreen || 100;
this._outputShiftBlue = options.outputShiftBlue || 0;
this._outputShiftAlpha = options.outputShiftAlpha || 255;
this._outputShiftOpacity = options.outputShiftOpacity || 0.7;
}
this._blockOut = options.blockOut || [];
if (typeof this._blockOut != 'object' && (this._blockOut.length !== undefined)) {
this._blockOut = [this._blockOut];
}
this._blockOut = options.blockOut || [];
if (typeof this._blockOut != 'object' && (this._blockOut.length !== undefined)) {
this._blockOut = [this._blockOut];
}
this._blockOutRed = options.blockOutRed || 0;
this._blockOutGreen = options.blockOutGreen || 0;
this._blockOutBlue = options.blockOutBlue || 0;
this._blockOutAlpha = options.blockOutAlpha || 255;
this._blockOutOpacity = options.blockOutOpacity || 1.0;
this._blockOutRed = options.blockOutRed || 0;
this._blockOutGreen = options.blockOutGreen || 0;
this._blockOutBlue = options.blockOutBlue || 0;
this._blockOutAlpha = options.blockOutAlpha || 255;
this._blockOutOpacity = options.blockOutOpacity || 1.0;
this._copyImageAToOutput = options.copyImageAToOutput || true;
this._copyImageBToOutput = options.copyImageBToOutput || false;
this._copyImageAToOutput = options.copyImageAToOutput || true;
this._copyImageBToOutput = options.copyImageBToOutput || false;
this._filter = options.filter || [];
this._filter = options.filter || [];
this._debug = options.debug || false;
this._debug = options.debug || false;
this._composition = options.composition || true;
this._composeLeftToRight = options.composeLeftToRight || false;
this._composeTopToBottom = options.composeTopToBottom || false;
this._composition = options.composition || true;
this._composeLeftToRight = options.composeLeftToRight || false;
this._composeTopToBottom = options.composeTopToBottom || false;
this._hShift = options.hShift || 2;
this._vShift = options.vShift || 2;
this._hShift = options.hShift || 2;
this._vShift = options.vShift || 2;
this._cropImageA = options.cropImageA;
this._cropImageB = options.cropImageB;
this._cropImageA = options.cropImageA;
this._cropImageB = options.cropImageB;
// Prepare reference white
this._refWhite = this._convertRgbToXyz({ c1:1, c2:1, c3:1, c4:1 });
// Prepare reference white
this._refWhite = this._convertRgbToXyz({c1: 1, c2: 1, c3: 1, c4: 1});
this._perceptual = options.perceptual || false;
this._perceptual = options.perceptual || false;
this._gamma = options.gamma;
this._gammaR = options.gammaR;
this._gammaG = options.gammaG;
this._gammaB = options.gammaB;
this._gamma = options.gamma;
this._gammaR = options.gammaR;
this._gammaG = options.gammaG;
this._gammaB = options.gammaB;
}

@@ -315,24 +315,24 @@

/**
* Runs the comparison with a promise
*
* @method runWithPromise
* @example
* var blinkDiff = BlinkDiff(...);
* blinkDiff.runWithPromise().then(function (result) {
/**
* Runs the comparison with a promise
*
* @method runWithPromise
* @example
* var blinkDiff = BlinkDiff(...);
* blinkDiff.runWithPromise().then(function (result) {
* ...
* });
* @return {Promise}
*/
runWithPromise: function () {
return Promise.denodeify(this.run).call(this);
},
* @return {Promise}
*/
runWithPromise: function () {
return Promise.denodeify(this.run).call(this);
},
/**
* Runs the comparison in node-style
*
* @method run
* @example
* var blinkDiff = BlinkDiff(...);
* blinkDiff.run(function (err, result) {
/**
* Runs the comparison in node-style
*
* @method run
* @example
* var blinkDiff = BlinkDiff(...);
* blinkDiff.run(function (err, result) {
* if (err) {

@@ -344,776 +344,722 @@ * throw err;

* });
*
* @param {function} fn
*/
run: function (fn) {
*
* @param {function} fn
*/
run: function (fn) {
var promise = Promise.resolve(),
result;
var promise = Promise.resolve(), result;
PNGImage.log = function (text) {
this.log('ERROR: ' + text);
throw new Error('ERROR: ' + text);
}.bind(this);
PNGImage.log = function (text) {
this.log('ERROR: ' + text);
throw new Error('ERROR: ' + text);
}.bind(this);
promise.then(function () {
return this._loadImage(this._imageAPath, this._imageA);
promise.then(function () {
return this._loadImage(this._imageAPath, this._imageA);
}.bind(this)).then(function (imageA) {
this._imageA = imageA;
return this._loadImage(this._imageBPath, this._imageB);
}.bind(this)).then(function (imageA) {
this._imageA = imageA;
return this._loadImage(this._imageBPath, this._imageB);
}.bind(this)).then(function (imageB) {
}.bind(this)).then(function (imageB) {
var gamma,
i, len,
rect,
color;
var gamma, i, len, rect, color;
this._imageB = imageB;
this._imageB = imageB;
// Crop images if requested
if (this._cropImageA) {
this._correctDimensions(this._imageA.getWidth(), this._imageA.getHeight(), this._cropImageA);
this._crop("Image-A", this._imageA, this._cropImageA);
}
if (this._cropImageB) {
this._correctDimensions(this._imageB.getWidth(), this._imageB.getHeight(), this._cropImageB);
this._crop("Image-B", this._imageB, this._cropImageB);
}
// Crop images if requested
if (this._cropImageA) {
this._correctDimensions(this._imageA.getWidth(), this._imageA.getHeight(), this._cropImageA);
this._crop("Image-A", this._imageA, this._cropImageA);
}
if (this._cropImageB) {
this._correctDimensions(this._imageB.getWidth(), this._imageB.getHeight(), this._cropImageB);
this._crop("Image-B", this._imageB, this._cropImageB);
}
// Always clip
this._clip(this._imageA, this._imageB);
// Always clip
this._clip(this._imageA, this._imageB);
this._imageOutput = PNGImage.createImage(this._imageA.getWidth(), this._imageA.getHeight());
this._imageOutput = PNGImage.createImage(this._imageA.getWidth(), this._imageA.getHeight());
// Make a copy when not in debug mode
if (this._debug) {
this._imageACompare = this._imageA;
this._imageBCompare = this._imageB;
} else {
this._imageACompare = PNGImage.copyImage(this._imageA);
this._imageBCompare = PNGImage.copyImage(this._imageB);
}
// Make a copy when not in debug mode
if (this._debug) {
this._imageACompare = this._imageA;
this._imageBCompare = this._imageB;
} else {
this._imageACompare = PNGImage.copyImage(this._imageA);
this._imageBCompare = PNGImage.copyImage(this._imageB);
}
// Block-out
color = {
red: this._blockOutRed,
green: this._blockOutGreen,
blue: this._blockOutBlue,
alpha: this._blockOutAlpha,
opacity: this._blockOutOpacity
};
for (i = 0, len = this._blockOut.length; i < len; i++) {
rect = this._blockOut[i];
// Block-out
color = {
red: this._blockOutRed,
green: this._blockOutGreen,
blue: this._blockOutBlue,
alpha: this._blockOutAlpha,
opacity: this._blockOutOpacity
};
for (i = 0, len = this._blockOut.length; i < len; i++) {
rect = this._blockOut[i];
// Make sure the block-out parameters fit
this._correctDimensions(this._imageACompare.getWidth(), this._imageACompare.getHeight(), rect);
// Make sure the block-out parameters fit
this._correctDimensions(this._imageACompare.getWidth(), this._imageACompare.getHeight(), rect);
this._imageACompare.fillRect(rect.x, rect.y, rect.width, rect.height, color);
this._imageBCompare.fillRect(rect.x, rect.y, rect.width, rect.height, color);
}
this._imageACompare.fillRect(rect.x, rect.y, rect.width, rect.height, color);
this._imageBCompare.fillRect(rect.x, rect.y, rect.width, rect.height, color);
}
// Copy image to composition
if (this._copyImageAToOutput) {
this._copyImage(this._debug ? this._imageACompare : this._imageA, this._imageOutput);
} else if (this._copyImageBToOutput) {
this._copyImage(this._debug ? this._imageBCompare : this._imageB, this._imageOutput);
}
// Copy image to composition
if (this._copyImageAToOutput) {
this._copyImage(this._debug ? this._imageACompare : this._imageA, this._imageOutput);
} else if (this._copyImageBToOutput) {
this._copyImage(this._debug ? this._imageBCompare : this._imageB, this._imageOutput);
}
// Apply all filters
this._imageACompare.applyFilters(this._filter);
this._imageBCompare.applyFilters(this._filter);
// Apply all filters
this._imageACompare.applyFilters(this._filter);
this._imageBCompare.applyFilters(this._filter);
// Gamma correction
if (this._gamma || this._gammaR || this._gammaG || this._gammaB) {
gamma = {
r: this._gammaR || this._gamma,
g: this._gammaG || this._gamma,
b: this._gammaB || this._gamma
};
}
// Gamma correction
if (this._gamma || this._gammaR || this._gammaG || this._gammaB) {
gamma = {
r: this._gammaR || this._gamma, g: this._gammaG || this._gamma, b: this._gammaB || this._gamma
};
}
// Comparison
result = this._compare(this._imageACompare, this._imageBCompare, this._imageOutput, this._delta,
{ // Output-Mask color
red: this._outputMaskRed,
green: this._outputMaskGreen,
blue: this._outputMaskBlue,
alpha: this._outputMaskAlpha,
opacity: this._outputMaskOpacity
},
{ // Output-Shift color
red: this._outputShiftRed,
green: this._outputShiftGreen,
blue: this._outputShiftBlue,
alpha: this._outputShiftAlpha,
opacity: this._outputShiftOpacity
},
{ // Background color
red: this._outputBackgroundRed,
green: this._outputBackgroundGreen,
blue: this._outputBackgroundBlue,
alpha: this._outputBackgroundAlpha,
opacity: this._outputBackgroundOpacity
},
this._hShift,
this._vShift,
this._perceptual,
gamma
);
// Comparison
result = this._compare(this._imageACompare, this._imageBCompare, this._imageOutput, this._delta, { // Output-Mask color
red: this._outputMaskRed,
green: this._outputMaskGreen,
blue: this._outputMaskBlue,
alpha: this._outputMaskAlpha,
opacity: this._outputMaskOpacity
}, { // Output-Shift color
red: this._outputShiftRed,
green: this._outputShiftGreen,
blue: this._outputShiftBlue,
alpha: this._outputShiftAlpha,
opacity: this._outputShiftOpacity
}, { // Background color
red: this._outputBackgroundRed,
green: this._outputBackgroundGreen,
blue: this._outputBackgroundBlue,
alpha: this._outputBackgroundAlpha,
opacity: this._outputBackgroundOpacity
}, this._hShift, this._vShift, this._perceptual, gamma);
// Create composition if requested
if (this._debug) {
this._imageOutput = this._createComposition(this._imageACompare, this._imageBCompare, this._imageOutput);
} else {
this._imageOutput = this._createComposition(this._imageA, this._imageB, this._imageOutput);
}
// Create composition if requested
if (this._debug) {
this._imageOutput = this._createComposition(this._imageACompare, this._imageBCompare, this._imageOutput);
} else {
this._imageOutput = this._createComposition(this._imageA, this._imageB, this._imageOutput);
}
// Need to write to the filesystem?
if (this._imageOutputPath && this._withinOutputLimit(result.code, this._imageOutputLimit)) {
this._imageOutput.writeImage(this._imageOutputPath, function (err) {
if (err) {
fn(err);
} else {
this.log("Wrote differences to " + this._imageOutputPath);
fn(undefined, result);
}
}.bind(this));
} else {
fn(undefined, result);
}
// Need to write to the filesystem?
if (this._imageOutputPath && this._withinOutputLimit(result.code, this._imageOutputLimit)) {
this._imageOutput.writeImage(this._imageOutputPath, function (err) {
if (err) {
fn(err);
} else {
this.log("Wrote differences to " + this._imageOutputPath);
fn(undefined, result);
}
}.bind(this));
} else {
fn(undefined, result);
}
}.bind(this)).then(null, function (err) {
console.error(err.stack);
fn(err);
});
},
}.bind(this)).then(null, function (err) {
console.error(err.stack);
fn(err);
});
},
/**
* Determines if result is within the output limit
*
* @method _withinOutputLimit
* @param {int} resultCode
* @param {int} outputLimit
* @return {boolean}
* @private
*/
_withinOutputLimit: function (resultCode, outputLimit) {
return this._convertResultCodeToRelativeValue(resultCode) <= outputLimit;
},
/**
* Determines if result is within the output limit
*
* @method _withinOutputLimit
* @param {int} resultCode
* @param {int} outputLimit
* @return {boolean}
* @private
*/
_withinOutputLimit: function (resultCode, outputLimit) {
return this._convertResultCodeToRelativeValue(resultCode) <= outputLimit;
},
/**
* Converts the result-code to a relative value
*
* @method _convertResultCodeToRelativeValue
* @param {int} resultCode
* @return {int}
* @private
*/
_convertResultCodeToRelativeValue: function (resultCode) {
/**
* Converts the result-code to a relative value
*
* @method _convertResultCodeToRelativeValue
* @param {int} resultCode
* @return {int}
* @private
*/
_convertResultCodeToRelativeValue: function (resultCode) {
var valueMap = {
0: 0,
1: 10,
7: 20,
5: 30
};
var valueMap = {
0: 0, 1: 10, 7: 20, 5: 30
};
return valueMap[resultCode] !== undefined ? valueMap[resultCode] : 0;
},
return valueMap[resultCode] !== undefined ? valueMap[resultCode] : 0;
},
/**
* Creates a comparison image
*
* @method _createComposition
* @param {PNGImage} imageA
* @param {PNGImage} imageB
* @param {PNGImage} imageOutput
* @return {PNGImage}
* @private
*/
_createComposition: function (imageA, imageB, imageOutput) {
/**
* Creates a comparison image
*
* @method _createComposition
* @param {PNGImage} imageA
* @param {PNGImage} imageB
* @param {PNGImage} imageOutput
* @return {PNGImage}
* @private
*/
_createComposition: function (imageA, imageB, imageOutput) {
var width,
height,
image = imageOutput;
var width, height, image = imageOutput;
if (this._composition) {
width = Math.max(imageA.getWidth(), imageB.getWidth());
height = Math.max(imageA.getHeight(), imageB.getHeight());
if (this._composition) {
width = Math.max(imageA.getWidth(), imageB.getWidth());
height = Math.max(imageA.getHeight(), imageB.getHeight());
if (((width > height) && !this._composeLeftToRight) || this._composeTopToBottom) {
image = PNGImage.createImage(width, height * 3);
if (((width > height) && !this._composeLeftToRight) || this._composeTopToBottom) {
image = PNGImage.createImage(width, height * 3);
imageA.getImage().bitblt(image.getImage(), 0, 0, imageA.getWidth(), imageA.getHeight(), 0, 0);
imageOutput.getImage().bitblt(image.getImage(), 0, 0, imageOutput.getWidth(), imageOutput.getHeight(), 0, height);
imageB.getImage().bitblt(image.getImage(), 0, 0, imageB.getWidth(), imageB.getHeight(), 0, height * 2);
} else {
image = PNGImage.createImage(width * 3, height);
imageA.getImage().bitblt(image.getImage(), 0, 0, imageA.getWidth(), imageA.getHeight(), 0, 0);
imageOutput.getImage().bitblt(image.getImage(), 0, 0, imageOutput.getWidth(), imageOutput.getHeight(), 0, height);
imageB.getImage().bitblt(image.getImage(), 0, 0, imageB.getWidth(), imageB.getHeight(), 0, height * 2);
} else {
image = PNGImage.createImage(width * 3, height);
imageA.getImage().bitblt(image.getImage(), 0, 0, imageA.getWidth(), imageA.getHeight(), 0, 0);
imageOutput.getImage().bitblt(image.getImage(), 0, 0, imageOutput.getWidth(), imageOutput.getHeight(), width, 0);
imageB.getImage().bitblt(image.getImage(), 0, 0, imageB.getWidth(), imageB.getHeight(), width * 2, 0);
}
}
imageA.getImage().bitblt(image.getImage(), 0, 0, imageA.getWidth(), imageA.getHeight(), 0, 0);
imageOutput.getImage().bitblt(image.getImage(), 0, 0, imageOutput.getWidth(), imageOutput.getHeight(), width, 0);
imageB.getImage().bitblt(image.getImage(), 0, 0, imageB.getWidth(), imageB.getHeight(), width * 2, 0);
}
}
return image;
},
return image;
},
/**
* Loads the image or uses the already available image
*
* @method _loadImage
* @param {string} path
* @param {PNGImage} image
* @return {PNGImage|Promise}
* @private
*/
_loadImage: function (path, image) {
/**
* Loads the image or uses the already available image
*
* @method _loadImage
* @param {string} path
* @param {PNGImage} image
* @return {PNGImage|Promise}
* @private
*/
_loadImage: function (path, image) {
if (image instanceof Buffer) {
return Promise.denodeify(PNGImage.loadImage)(image);
if (image instanceof Buffer) {
return Promise.denodeify(PNGImage.loadImage)(image);
} else if ((typeof path === 'string') && !image) {
return Promise.denodeify(PNGImage.readImage)(path);
} else if ((typeof path === 'string') && !image) {
return Promise.denodeify(PNGImage.readImage)(path);
} else {
return image;
}
},
} else {
return image;
}
},
/**
* Copies one image into another image
*
* @method _copyImage
* @param {PNGImage} imageSrc
* @param {PNGImage} imageDst
* @private
*/
_copyImage: function (imageSrc, imageDst) {
imageSrc.getImage().bitblt(
imageDst.getImage(),
0, 0,
imageSrc.getWidth(),
imageSrc.getHeight(),
0, 0
);
},
/**
* Copies one image into another image
*
* @method _copyImage
* @param {PNGImage} imageSrc
* @param {PNGImage} imageDst
* @private
*/
_copyImage: function (imageSrc, imageDst) {
imageSrc.getImage().bitblt(imageDst.getImage(), 0, 0, imageSrc.getWidth(), imageSrc.getHeight(), 0, 0);
},
/**
* Is the difference above the set threshold?
*
* @method isAboveThreshold
* @param {int} items
* @param {int} [total]
* @return {boolean}
*/
isAboveThreshold: function (items, total) {
/**
* Is the difference above the set threshold?
*
* @method isAboveThreshold
* @param {int} items
* @param {int} [total]
* @return {boolean}
*/
isAboveThreshold: function (items, total) {
if ((this._thresholdType === BlinkDiff.THRESHOLD_PIXEL) && (this._threshold <= items)) {
return true;
if ((this._thresholdType === BlinkDiff.THRESHOLD_PIXEL) && (this._threshold <= items)) {
return true;
} else if (this._threshold <= (items / total)) {
return true;
}
} else if (this._threshold <= (items / total)) {
return true;
}
return false;
},
return false;
},
/**
* Log method that can be overwritten to modify the logging behavior.
*
* @method log
* @param {string} text
*/
log: function (text) {
// Nothing here; Overwrite this to add some functionality
},
/**
* Log method that can be overwritten to modify the logging behavior.
*
* @method log
* @param {string} text
*/
log: function (text) {
// Nothing here; Overwrite this to add some functionality
},
/**
* Has comparison passed?
*
* @method hasPassed
* @param {int} result Comparison result-code
* @return {boolean}
*/
hasPassed: function (result) {
return ((result !== BlinkDiff.RESULT_DIFFERENT) && (result !== BlinkDiff.RESULT_UNKNOWN));
},
/**
* Has comparison passed?
*
* @method hasPassed
* @param {int} result Comparison result-code
* @return {boolean}
*/
hasPassed: function (result) {
return ((result !== BlinkDiff.RESULT_DIFFERENT) && (result !== BlinkDiff.RESULT_UNKNOWN));
},
/**
* Clips the images to the lower resolution of both
*
* @private
* @method _clip
* @param {PNGImage} imageA Source image
* @param {PNGImage} imageB Destination image
*/
_clip: function (imageA, imageB) {
/**
* Clips the images to the lower resolution of both
*
* @private
* @method _clip
* @param {PNGImage} imageA Source image
* @param {PNGImage} imageB Destination image
*/
_clip: function (imageA, imageB) {
var minWidth,
minHeight;
var minWidth, minHeight;
if ((imageA.getWidth() != imageB.getWidth()) || (imageA.getHeight() != imageB.getHeight())) {
if ((imageA.getWidth() != imageB.getWidth()) || (imageA.getHeight() != imageB.getHeight())) {
minWidth = imageA.getWidth();
if (imageB.getWidth() < minWidth) {
minWidth = imageB.getWidth();
}
minWidth = imageA.getWidth();
if (imageB.getWidth() < minWidth) {
minWidth = imageB.getWidth();
}
minHeight = imageA.getHeight();
if (imageB.getHeight() < minHeight) {
minHeight = imageB.getHeight();
}
minHeight = imageA.getHeight();
if (imageB.getHeight() < minHeight) {
minHeight = imageB.getHeight();
}
this.log("Clipping to " + minWidth + " x " + minHeight);
this.log("Clipping to " + minWidth + " x " + minHeight);
imageA.clip(0, 0, minWidth, minHeight);
imageB.clip(0, 0, minWidth, minHeight);
}
},
imageA.clip(0, 0, minWidth, minHeight);
imageB.clip(0, 0, minWidth, minHeight);
}
},
/**
* Crops the source image to the bounds of rect
*
* @method _crop
* @param {string} which Title of image to crop
* @param {PNGImage} image Source image
* @param {object} rect Values for rect
* @param {int} rect.x X value of rect
* @param {int} rect.y Y value of rect
* @param {int} rect.width Width value of rect
* @param {int} rect.height Height value of rect
* @private
*/
_crop: function (which, image, rect) {
/**
* Crops the source image to the bounds of rect
*
* @method _crop
* @param {string} which Title of image to crop
* @param {PNGImage} image Source image
* @param {object} rect Values for rect
* @param {int} rect.x X value of rect
* @param {int} rect.y Y value of rect
* @param {int} rect.width Width value of rect
* @param {int} rect.height Height value of rect
* @private
*/
_crop: function (which, image, rect) {
this.log("Cropping " + which + " from " + rect.x + "," + rect.y + " by " + rect.width + " x " + rect.height);
this.log("Cropping " + which + " from " + rect.x + "," + rect.y + " by " + rect.width + " x " + rect.height);
image.clip(rect.x, rect.y, rect.width, rect.height);
},
image.clip(rect.x, rect.y, rect.width, rect.height);
},
/**
* Correcting area dimensions if necessary
*
* Note:
* Priority is on the x/y coordinates, and not on the size since the size will then be removed anyways.
*
* @method _correctDimensions
* @param {int} width
* @param {int} height
* @param {object} rect Values for rect
* @param {int} rect.x X value of rect
* @param {int} rect.y Y value of rect
* @param {int} rect.width Width value of rect
* @param {int} rect.height Height value of rect
* @private
*/
_correctDimensions: function (width, height, rect) {
/**
* Correcting area dimensions if necessary
*
* Note:
* Priority is on the x/y coordinates, and not on the size since the size will then be removed anyways.
*
* @method _correctDimensions
* @param {int} width
* @param {int} height
* @param {object} rect Values for rect
* @param {int} rect.x X value of rect
* @param {int} rect.y Y value of rect
* @param {int} rect.width Width value of rect
* @param {int} rect.height Height value of rect
* @private
*/
_correctDimensions: function (width, height, rect) {
// Set values if none given
rect.x = rect.x || 0;
rect.y = rect.y || 0;
rect.width = rect.width || width;
rect.height = rect.height || height;
// Set values if none given
rect.x = rect.x || 0;
rect.y = rect.y || 0;
rect.width = rect.width || width;
rect.height = rect.height || height;
// Check negative values
rect.x = Math.max(0, rect.x);
rect.y = Math.max(0, rect.y);
rect.width = Math.max(0, rect.width);
rect.height = Math.max(0, rect.height);
// Check negative values
rect.x = Math.max(0, rect.x);
rect.y = Math.max(0, rect.y);
rect.width = Math.max(0, rect.width);
rect.height = Math.max(0, rect.height);
// Check dimensions
rect.x = Math.min(rect.x, width - 1); // -1 to make sure that there is an image
rect.y = Math.min(rect.y, height - 1);
rect.width = Math.min(rect.width, width - rect.x);
rect.height = Math.min(rect.height, height - rect.y);
},
// Check dimensions
rect.x = Math.min(rect.x, width - 1); // -1 to make sure that there is an image
rect.y = Math.min(rect.y, height - 1);
rect.width = Math.min(rect.width, width - rect.x);
rect.height = Math.min(rect.height, height - rect.y);
},
/**
* Calculates the distance of colors in the 4 dimensional color space
*
* @method _colorDelta
* @param {object} color1 Values for color 1
* @param {int} color1.c1 First value of color 1
* @param {int} color1.c2 Second value of color 1
* @param {int} color1.c3 Third value of color 1
* @param {int} color1.c4 Fourth value of color 1
* @param {object} color2 Values for color 2
* @param {int} color2.c1 First value of color 2
* @param {int} color2.c2 Second value of color 2
* @param {int} color2.c3 Third value of color 2
* @param {int} color2.c4 Fourth value of color 2
* @return {number} Distance
* @private
*/
_colorDelta: function (color1, color2) {
var c1, c2, c3, c4;
/**
* Calculates the distance of colors in the 4 dimensional color space
*
* @method _colorDelta
* @param {object} color1 Values for color 1
* @param {int} color1.c1 First value of color 1
* @param {int} color1.c2 Second value of color 1
* @param {int} color1.c3 Third value of color 1
* @param {int} color1.c4 Fourth value of color 1
* @param {object} color2 Values for color 2
* @param {int} color2.c1 First value of color 2
* @param {int} color2.c2 Second value of color 2
* @param {int} color2.c3 Third value of color 2
* @param {int} color2.c4 Fourth value of color 2
* @return {number} Distance
* @private
*/
_colorDelta: function (color1, color2) {
var c1, c2, c3, c4;
c1 = Math.pow(color1.c1 - color2.c1, 2);
c2 = Math.pow(color1.c2 - color2.c2, 2);
c3 = Math.pow(color1.c3 - color2.c3, 2);
c4 = Math.pow(color1.c4 - color2.c4, 2);
c1 = Math.pow(color1.c1 - color2.c1, 2);
c2 = Math.pow(color1.c2 - color2.c2, 2);
c3 = Math.pow(color1.c3 - color2.c3, 2);
c4 = Math.pow(color1.c4 - color2.c4, 2);
return Math.sqrt(c1 + c2 + c3 + c4);
},
return Math.sqrt(c1 + c2 + c3 + c4);
},
/**
* Gets the color of an image by the index
*
* @method _getColor
* @param {PNGImage} image Image
* @param {int} idx Index of pixel in image
* @param {boolean} [perceptual=false]
* @param {object} [gamma]
* @return {object} Color
* @private
*/
_getColor: function (image, idx, perceptual, gamma) {
/**
* Gets the color of an image by the index
*
* @method _getColor
* @param {PNGImage} image Image
* @param {int} idx Index of pixel in image
* @param {boolean} [perceptual=false]
* @param {object} [gamma]
* @return {object} Color
* @private
*/
_getColor: function (image, idx, perceptual, gamma) {
var color;
var color;
color = {
c1: image.getRed(idx),
c2: image.getGreen(idx),
c3: image.getBlue(idx),
c4: image.getAlpha(idx)
};
color = {
c1: image.getRed(idx), c2: image.getGreen(idx), c3: image.getBlue(idx), c4: image.getAlpha(idx)
};
if (perceptual || gamma) {
color = this._correctGamma(color, gamma);
color = this._convertRgbToXyz(color);
color = this._convertXyzToCieLab(color);
}
if (perceptual || gamma) {
color = this._correctGamma(color, gamma);
color = this._convertRgbToXyz(color);
color = this._convertXyzToCieLab(color);
}
return color;
},
return color;
},
/**
* Correct gamma and return color in [0, 1] range
*
* @method _correctGamma
* @param {object} color
* @param {object} [gamma]
* @return {{c1: number, c2: number, c3: number, c4: number}}
* @private
*/
_correctGamma: function (color, gamma) {
/**
* Correct gamma and return color in [0, 1] range
*
* @method _correctGamma
* @param {object} color
* @param {object} [gamma]
* @return {{c1: number, c2: number, c3: number, c4: number}}
* @private
*/
_correctGamma: function (color, gamma) {
// Convert to range [0, 1]
var result = {
c1: color.c1 / 255,
c2: color.c2 / 255,
c3: color.c3 / 255,
c4: color.c4
};
// Convert to range [0, 1]
var result = {
c1: color.c1 / 255, c2: color.c2 / 255, c3: color.c3 / 255, c4: color.c4
};
if (gamma || gamma.R !== undefined || gamma.G !== undefined || gamma.B !== undefined) {
if (gamma.R !== undefined) {
result.c1 = Math.pow(result.c1, gamma.R);
}
if (gamma.G !== undefined) {
result.c2 = Math.pow(result.c2, gamma.G);
}
if (gamma.B !== undefined) {
result.c3 = Math.pow(result.c3, gamma.B);
}
}
if (gamma || gamma.R !== undefined || gamma.G !== undefined || gamma.B !== undefined) {
if (gamma.R !== undefined) {
result.c1 = Math.pow(result.c1, gamma.R);
}
if (gamma.G !== undefined) {
result.c2 = Math.pow(result.c2, gamma.G);
}
if (gamma.B !== undefined) {
result.c3 = Math.pow(result.c3, gamma.B);
}
}
return result;
},
return result;
},
/**
* Converts the color from RGB to XYZ
*
* @method _convertRgbToXyz
* @param {object} color
* @return {object}
* @private
*/
_convertRgbToXyz: function (color) {
var result = {};
/**
* Converts the color from RGB to XYZ
*
* @method _convertRgbToXyz
* @param {object} color
* @return {object}
* @private
*/
_convertRgbToXyz: function (color) {
var result = {};
result.c1 = color.c1 * 0.4887180 + color.c2 * 0.3106803 + color.c3 * 0.2006017;
result.c2 = color.c1 * 0.1762044 + color.c2 * 0.8129847 + color.c3 * 0.0108109;
result.c3 = color.c2 * 0.0102048 + color.c3 * 0.9897952;
result.c4 = color.c4;
result.c1 = color.c1 * 0.4887180 + color.c2 * 0.3106803 + color.c3 * 0.2006017;
result.c2 = color.c1 * 0.1762044 + color.c2 * 0.8129847 + color.c3 * 0.0108109;
result.c3 = color.c2 * 0.0102048 + color.c3 * 0.9897952;
result.c4 = color.c4;
return result;
},
return result;
},
/**
* Converts the color from XYZ to CieLab
*
* @method _convertXyzToCieLab
* @param {object} color
* @return {object}
* @private
*/
_convertXyzToCieLab: function (color) {
var result = {},
c1, c2, c3;
/**
* Converts the color from XYZ to CieLab
*
* @method _convertXyzToCieLab
* @param {object} color
* @return {object}
* @private
*/
_convertXyzToCieLab: function (color) {
var result = {}, c1, c2, c3;
function f (t) {
return (t > 0.00885645167904) ? Math.pow(t, 1/3) : 70.08333333333263 * t + 0.13793103448276;
}
function f (t) {
return (t > 0.00885645167904) ? Math.pow(t, 1 / 3) : 70.08333333333263 * t + 0.13793103448276;
}
c1 = f(color.c1 / this._refWhite.c1);
c2 = f(color.c2 / this._refWhite.c2);
c3 = f(color.c3 / this._refWhite.c3);
c1 = f(color.c1 / this._refWhite.c1);
c2 = f(color.c2 / this._refWhite.c2);
c3 = f(color.c3 / this._refWhite.c3);
result.c1 = (116 * c2) - 16;
result.c2 = 500 * (c1 - c2);
result.c3 = 200 * (c2 - c3);
result.c4 = color.c4;
result.c1 = (116 * c2) - 16;
result.c2 = 500 * (c1 - c2);
result.c3 = 200 * (c2 - c3);
result.c4 = color.c4;
return result;
},
return result;
},
/**
* Calculates the lower limit
*
* @param {int} value
* @param {int} min
* @param {int} shift
* @return {int}
* @private
*/
_calculateLowerLimit: function (value, min, shift) {
return (value - shift) < min ? -(shift + (value - shift)) : -shift;
},
/**
* Calculates the lower limit
*
* @method _calculateLowerLimit
* @param {int} value
* @param {int} min
* @param {int} shift
* @return {int}
* @private
*/
_calculateLowerLimit: function (value, min, shift) {
return (value - shift) < min ? -(shift + (value - shift)) : -shift;
},
/**
* Calculates the upper limit
*
* @param {int} value
* @param {int} max
* @param {int} shift
* @return {int}
* @private
*/
_calculateUpperLimit: function (value, max, shift) {
return (value + shift) > max ? (max - value) : shift;
},
/**
* Calculates the upper limit
*
* @method _calculateUpperLimit
* @param {int} value
* @param {int} max
* @param {int} shift
* @return {int}
* @private
*/
_calculateUpperLimit: function (value, max, shift) {
return (value + shift) > max ? (max - value) : shift;
},
/**
* Checks if any pixel in the shift surrounding has a comparable color
*
* @param {int} x
* @param {int} y
* @param {object} color
* @param {number} deltaThreshold
* @param {PNGImage} imageA
* @param {PNGImage} imageB
* @param {int} width
* @param {int} height
* @param {int} hShift
* @param {int} vShift
* @param {boolean} [perceptual=false]
* @param {object} [gamma]
* @return {boolean} Is pixel within delta found in surrounding?
* @private
*/
_shiftCompare: function (x, y, color, deltaThreshold, imageA, imageB, width, height, hShift, vShift, perceptual, gamma) {
/**
* Checks if any pixel in the shift surrounding has a comparable color
*
* @method _shiftCompare
* @param {int} x
* @param {int} y
* @param {object} color
* @param {number} deltaThreshold
* @param {PNGImage} imageA
* @param {PNGImage} imageB
* @param {int} width
* @param {int} height
* @param {int} hShift
* @param {int} vShift
* @param {boolean} [perceptual=false]
* @param {object} [gamma]
* @return {boolean} Is pixel within delta found in surrounding?
* @private
*/
_shiftCompare: function (x, y, color, deltaThreshold, imageA, imageB, width, height, hShift, vShift, perceptual, gamma) {
var i,
xOffset, xLow, xHigh,
yOffset, yLow, yHigh,
delta,
color1,
color2,
localDeltaThreshold;
var i, xOffset, xLow, xHigh, yOffset, yLow, yHigh, delta, color1, color2, localDeltaThreshold;
if ((hShift > 0) || (vShift > 0)) {
if ((hShift > 0) || (vShift > 0)) {
xLow = this._calculateLowerLimit(x, 0, hShift);
xHigh = this._calculateUpperLimit(x, width - 1, hShift);
xLow = this._calculateLowerLimit(x, 0, hShift);
xHigh = this._calculateUpperLimit(x, width - 1, hShift);
yLow = this._calculateLowerLimit(y, 0, vShift);
yHigh = this._calculateUpperLimit(y, height - 1, vShift);
yLow = this._calculateLowerLimit(y, 0, vShift);
yHigh = this._calculateUpperLimit(y, height - 1, vShift);
for (xOffset = xLow; xOffset <= xHigh; xOffset++) {
for (yOffset = yLow; yOffset <= yHigh; yOffset++) {
for (xOffset = xLow; xOffset <= xHigh; xOffset++) {
for (yOffset = yLow; yOffset <= yHigh; yOffset++) {
if ((xOffset != 0) || (yOffset != 0)) {
if ((xOffset != 0) || (yOffset != 0)) {
i = imageB.getIndex(x + xOffset, y + yOffset);
i = imageB.getIndex(x + xOffset, y + yOffset);
color1 = this._getColor(imageA, i, perceptual, gamma);
localDeltaThreshold = this._colorDelta(color, color1);
color1 = this._getColor(imageA, i, perceptual, gamma);
localDeltaThreshold = this._colorDelta(color, color1);
color2 = this._getColor(imageB, i, perceptual, gamma);
delta = this._colorDelta(color, color2);
color2 = this._getColor(imageB, i, perceptual, gamma);
delta = this._colorDelta(color, color2);
if ((Math.abs(delta - localDeltaThreshold) < deltaThreshold) && (localDeltaThreshold > deltaThreshold)) {
return true;
}
}
}
}
}
if ((Math.abs(delta - localDeltaThreshold) < deltaThreshold) && (localDeltaThreshold > deltaThreshold)) {
return true;
}
}
}
}
}
return false;
},
return false;
},
/**
* Does a quick comparison between the supplied images
*
* @method _pixelCompare
* @param {PNGImage} imageA
* @param {PNGImage} imageB
* @param {PNGImage} imageOutput
* @param {number} deltaThreshold
* @param {int} width Width of image
* @param {int} height Height of image
* @param {object} outputMaskColor
* @param {int} [outputMaskColor.red]
* @param {int} [outputMaskColor.green]
* @param {int} [outputMaskColor.blue]
* @param {int} [outputMaskColor.alpha]
* @param {float} [outputMaskColor.opacity]
* @param {object} outputShiftColor
* @param {int} [outputShiftColor.red]
* @param {int} [outputShiftColor.green]
* @param {int} [outputShiftColor.blue]
* @param {int} [outputShiftColor.alpha]
* @param {float} [outputShiftColor.opacity]
* @param {object} backgroundColor
* @param {int} [backgroundColor.red]
* @param {int} [backgroundColor.green]
* @param {int} [backgroundColor.blue]
* @param {int} [backgroundColor.alpha]
* @param {float} [backgroundColor.opacity]
* @param {int} [hShift=0] Horizontal shift
* @param {int} [vShift=0] Vertical shift
* @param {boolean} [perceptual=false]
* @param {object} [gamma]
* @return {int} Number of pixel differences
* @private
*/
_pixelCompare: function (imageA, imageB, imageOutput, deltaThreshold, width, height, outputMaskColor, outputShiftColor, backgroundColor, hShift, vShift, perceptual, gamma) {
var difference = 0,
i,
x, y,
delta,
color1, color2;
/**
* Does a quick comparison between the supplied images
*
* @method _pixelCompare
* @param {PNGImage} imageA
* @param {PNGImage} imageB
* @param {PNGImage} imageOutput
* @param {number} deltaThreshold
* @param {int} width Width of image
* @param {int} height Height of image
* @param {object} outputMaskColor
* @param {int} [outputMaskColor.red]
* @param {int} [outputMaskColor.green]
* @param {int} [outputMaskColor.blue]
* @param {int} [outputMaskColor.alpha]
* @param {float} [outputMaskColor.opacity]
* @param {object} outputShiftColor
* @param {int} [outputShiftColor.red]
* @param {int} [outputShiftColor.green]
* @param {int} [outputShiftColor.blue]
* @param {int} [outputShiftColor.alpha]
* @param {float} [outputShiftColor.opacity]
* @param {object} backgroundColor
* @param {int} [backgroundColor.red]
* @param {int} [backgroundColor.green]
* @param {int} [backgroundColor.blue]
* @param {int} [backgroundColor.alpha]
* @param {float} [backgroundColor.opacity]
* @param {int} [hShift=0] Horizontal shift
* @param {int} [vShift=0] Vertical shift
* @param {boolean} [perceptual=false]
* @param {object} [gamma]
* @return {int} Number of pixel differences
* @private
*/
_pixelCompare: function (imageA, imageB, imageOutput, deltaThreshold, width, height, outputMaskColor, outputShiftColor, backgroundColor, hShift, vShift, perceptual, gamma) {
var difference = 0, i, x, y, delta, color1, color2;
for (x = 0; x < width; x++) {
for (y = 0; y < height; y++) {
i = imageA.getIndex(x, y);
for (x = 0; x < width; x++) {
for (y = 0; y < height; y++) {
i = imageA.getIndex(x, y);
color1 = this._getColor(imageA, i, perceptual, gamma);
color2 = this._getColor(imageB, i, perceptual, gamma);
color1 = this._getColor(imageA, i, perceptual, gamma);
color2 = this._getColor(imageB, i, perceptual, gamma);
delta = this._colorDelta(color1, color2);
delta = this._colorDelta(color1, color2);
if (delta > deltaThreshold) {
if (delta > deltaThreshold) {
if (this._shiftCompare(x, y, color1, deltaThreshold, imageA, imageB, width, height, hShift, vShift, perceptual, gamma) &&
this._shiftCompare(x, y, color2, deltaThreshold, imageB, imageA, width, height, hShift, vShift, perceptual, gamma)) {
imageOutput.setAtIndex(i, outputShiftColor);
} else {
difference++;
imageOutput.setAtIndex(i, outputMaskColor);
}
if (this._shiftCompare(x, y, color1, deltaThreshold, imageA, imageB, width, height, hShift, vShift, perceptual, gamma) && this._shiftCompare(x, y, color2, deltaThreshold, imageB, imageA, width, height, hShift, vShift, perceptual, gamma)) {
imageOutput.setAtIndex(i, outputShiftColor);
} else {
difference++;
imageOutput.setAtIndex(i, outputMaskColor);
}
} else {
imageOutput.setAtIndex(i, backgroundColor);
}
}
}
} else {
imageOutput.setAtIndex(i, backgroundColor);
}
}
}
return difference;
},
return difference;
},
/**
* Compares the two images supplied
*
* @method _compare
* @param {PNGImage} imageA
* @param {PNGImage} imageB
* @param {PNGImage} imageOutput
* @param {number} deltaThreshold
* @param {object} outputMaskColor
* @param {int} [outputMaskColor.red]
* @param {int} [outputMaskColor.green]
* @param {int} [outputMaskColor.blue]
* @param {int} [outputMaskColor.alpha]
* @param {float} [outputMaskColor.opacity]
* @param {object} outputShiftColor
* @param {int} [outputShiftColor.red]
* @param {int} [outputShiftColor.green]
* @param {int} [outputShiftColor.blue]
* @param {int} [outputShiftColor.alpha]
* @param {float} [outputShiftColor.opacity]
* @param {object} backgroundColor
* @param {int} [backgroundColor.red]
* @param {int} [backgroundColor.green]
* @param {int} [backgroundColor.blue]
* @param {int} [backgroundColor.alpha]
* @param {float} [backgroundColor.opacity]
* @param {int} [hShift=0] Horizontal shift
* @param {int} [vShift=0] Vertical shift
* @param {boolean} [perceptual=false]
* @param {object} [gamma]
* @return {object}
* @private
*/
_compare: function (imageA, imageB, imageOutput, deltaThreshold, outputMaskColor, outputShiftColor, backgroundColor, hShift, vShift, perceptual, gamma) {
/**
* Compares the two images supplied
*
* @method _compare
* @param {PNGImage} imageA
* @param {PNGImage} imageB
* @param {PNGImage} imageOutput
* @param {number} deltaThreshold
* @param {object} outputMaskColor
* @param {int} [outputMaskColor.red]
* @param {int} [outputMaskColor.green]
* @param {int} [outputMaskColor.blue]
* @param {int} [outputMaskColor.alpha]
* @param {float} [outputMaskColor.opacity]
* @param {object} outputShiftColor
* @param {int} [outputShiftColor.red]
* @param {int} [outputShiftColor.green]
* @param {int} [outputShiftColor.blue]
* @param {int} [outputShiftColor.alpha]
* @param {float} [outputShiftColor.opacity]
* @param {object} backgroundColor
* @param {int} [backgroundColor.red]
* @param {int} [backgroundColor.green]
* @param {int} [backgroundColor.blue]
* @param {int} [backgroundColor.alpha]
* @param {float} [backgroundColor.opacity]
* @param {int} [hShift=0] Horizontal shift
* @param {int} [vShift=0] Vertical shift
* @param {boolean} [perceptual=false]
* @param {object} [gamma]
* @return {object}
* @private
*/
_compare: function (imageA, imageB, imageOutput, deltaThreshold, outputMaskColor, outputShiftColor, backgroundColor, hShift, vShift, perceptual, gamma) {
var result = {
code: BlinkDiff.RESULT_UNKNOWN,
differences: undefined,
dimension: undefined,
width: undefined,
height: undefined
};
var result = {
code: BlinkDiff.RESULT_UNKNOWN,
differences: undefined,
dimension: undefined,
width: undefined,
height: undefined
};
// Get some data needed for comparison
result.width = imageA.getWidth();
result.height = imageA.getHeight();
result.dimension = result.width * result.height;
// Get some data needed for comparison
result.width = imageA.getWidth();
result.height = imageA.getHeight();
result.dimension = result.width * result.height;
// Check if identical
result.differences = this._pixelCompare(
imageA,
imageB,
imageOutput,
deltaThreshold,
result.width,
result.height,
outputMaskColor,
outputShiftColor,
backgroundColor,
hShift, vShift,
perceptual,
gamma
);
// Check if identical
result.differences = this._pixelCompare(imageA, imageB, imageOutput, deltaThreshold, result.width, result.height, outputMaskColor, outputShiftColor, backgroundColor, hShift, vShift, perceptual, gamma);
// Result
if (result.differences == 0) {
this.log("Images are identical or near identical");
result.code = BlinkDiff.RESULT_IDENTICAL;
return result;
// Result
if (result.differences == 0) {
this.log("Images are identical or near identical");
result.code = BlinkDiff.RESULT_IDENTICAL;
return result;
} else if (this.isAboveThreshold(result.differences, result.dimension)) {
this.log("Images are visibly different");
this.log(result.differences + " pixels are different");
result.code = BlinkDiff.RESULT_DIFFERENT;
return result;
} else if (this.isAboveThreshold(result.differences, result.dimension)) {
this.log("Images are visibly different");
this.log(result.differences + " pixels are different");
result.code = BlinkDiff.RESULT_DIFFERENT;
return result;
} else {
this.log("Images are similar");
this.log(result.differences + " pixels are different");
result.code = BlinkDiff.RESULT_SIMILAR;
return result;
}
}
} else {
this.log("Images are similar");
this.log(result.differences + " pixels are different");
result.code = BlinkDiff.RESULT_SIMILAR;
return result;
}
}
};
module.exports = BlinkDiff;
{
"name": "blink-diff",
"version": "1.0.7",
"description": "A lightweight image comparison tool",
"license": "MIT",
"main": "index.js",
"bugs": "https://github.com/yahoo/blink-diff/issues",
"homepage": "https://github.com/yahoo/blink-diff",
"bin": {
"blink-diff": "bin/blink-diff"
},
"author": {
"name": "Marcel Erz",
"email": "erz@yahoo-inc.com"
},
"repository": {
"type": "git",
"url": "https://github.com/yahoo/blink-diff.git"
},
"scripts": {
"test": "istanbul cover -- _mocha --reporter spec",
"docs": "yuidoc ."
},
"keywords": [
"image-diff",
"blink",
"image",
"difference",
"compare"
],
"dependencies": {
"promise": "6.0.0",
"pngjs-image": "0.9.3"
},
"devDependencies": {
"chai": "1.9.1",
"coveralls": "2.11.2",
"istanbul": "0.3.2",
"mocha": "1.21.4",
"yuidocjs": "0.3.50"
}
"name": "blink-diff",
"version": "1.0.8",
"description": "A lightweight image comparison tool",
"license": "MIT",
"main": "index.js",
"bugs": "https://github.com/yahoo/blink-diff/issues",
"homepage": "https://github.com/yahoo/blink-diff",
"bin": {
"blink-diff": "bin/blink-diff"
},
"author": {
"name": "Marcel Erz",
"email": "erz@yahoo-inc.com",
"url": "http://www.marcelerz.com"
},
"repository": {
"type": "git",
"url": "https://github.com/yahoo/blink-diff.git"
},
"keywords": [
"image-diff",
"visual-diff",
"diff",
"testing",
"blink",
"image",
"difference",
"compare"
],
"scripts": {
"test": "istanbul cover -- _mocha --reporter spec",
"docs": "yuidoc ."
},
"dependencies": {
"promise": "6.0.0",
"pngjs-image": "0.9.3"
},
"devDependencies": {
"chai": "1.9.2",
"coveralls": "2.11.2",
"codeclimate-test-reporter": "0.0.4",
"istanbul": "0.3.2",
"mocha": "1.21.4",
"sinon": "1.12.2",
"sinon-chai": "2.7.0",
"yuidocjs": "0.3.50"
}
}

@@ -6,11 +6,16 @@ Blink-Diff

[![Build Status](https://secure.travis-ci.org/yahoo/blink-diff.png)](http://travis-ci.org/yahoo/blink-diff)
[![npm version](https://badge.fury.io/js/blink-diff.svg)](http://badge.fury.io/js/blink-diff)
[![Build Status](https://img.shields.io/travis/yahoo/blink-diff.svg)](http://travis-ci.org/yahoo/blink-diff)
[![Coveralls Coverage](https://img.shields.io/coveralls/yahoo/blink-diff.svg)](https://coveralls.io/r/yahoo/blink-diff)
[![Code Climate Grade](https://img.shields.io/codeclimate/github/yahoo/blink-diff.svg)](https://codeclimate.com/github/yahoo/blink-diff)
[![NPM](https://nodei.co/npm/blink-diff.png?downloads=true)](https://nodei.co/npm/blink-diff/)
[![NPM version](https://badge.fury.io/js/blink-diff.svg)](https://www.npmjs.com/package/blink-diff)
[![NPM License](https://img.shields.io/npm/l/blink-diff.svg)](https://www.npmjs.com/package/blink-diff)
[![NPM](https://nodei.co/npm/blink-diff.png?downloads=true&stars=true)](https://www.npmjs.com/package/blink-diff)
[![NPM](https://nodei.co/npm-dl/blink-diff.png?months=3&height=2)](https://www.npmjs.com/package/blink-diff)
[API-Documentation](http://yahoo.github.io/blink-diff/docs/)
[![Coverage Report](https://img.shields.io/badge/Coverage_Report-Available-blue.svg)](http://yahoo.github.io/blink-diff/coverage/lcov-report/)
[![API Documentation](https://img.shields.io/badge/API_Documentation-Available-blue.svg)](http://yahoo.github.io/blink-diff/docs/)
[Coverage Report](http://yahoo.github.io/blink-diff/coverage/lcov-report/)
[![Gitter Support](https://img.shields.io/badge/Support-Gitter_IM-yellow.svg)](https://gitter.im/preceptorjs/support)

@@ -26,2 +31,3 @@

* [Logging](#logging)
* [Block-Out](#block-out)
* [Examples](#examples)

@@ -109,7 +115,12 @@ * [Results](#results)

outputPath: 'path/to/output/image'
imageOutputPath: 'path/to/output/image'
});
diff.run(function (error) {
console.log(error ? 'Failed' : 'Passed');
diff.run(function (error, result) {
if (error) {
throw error;
} else {
console.log(diff.hasPassed(result.code) ? 'Passed' : 'Failed');
console.log('Found ' + result.differences + ' differences.');
}
});

@@ -190,4 +201,9 @@ ```

diff.run(function (error) {
console.log(error ? 'Failed' : 'Passed');
diff.run(function (error, result) {
if (error) {
throw error;
} else {
console.log(diff.hasPassed(result.code) ? 'Passed' : 'Failed');
console.log('Found ' + result.differences + ' differences.');
}
});

@@ -284,2 +300,6 @@ });

* Block-out areas
* [jeffposnick](https://github.com/jeffposnick)
* Documentation
* [a-nwhitmont](https://github.com/a-nwhitmont)
* Documentation

@@ -296,4 +316,8 @@ ##Third-party libraries

* chai: http://chaijs.com
* coveralls: https://github.com/cainus/node-coveralls
* codeclimate-test-reporter: https://github.com/codeclimate/javascript-test-reporter
* istanbul: https://github.com/gotwarlost/istanbul
* mocha: https://github.com/visionmedia/mocha
* sinon: http://sinonjs.org
* sinon-chai: https://github.com/domenic/sinon-chai
* yuidocjs: https://github.com/yui/yuidoc

@@ -305,2 +329,2 @@

Copyright 2014 Yahoo Inc.
Copyright 2014-2015 Yahoo Inc.
{
"options": {
"outdir": "docs",
"linkNatives": true,
"exclude": "test,bin"
}
}
"options": {
"outdir": "docs",
"linkNatives": true,
"exclude": "test,bin"
}
}

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc