Skip to content

Commit

Permalink
support compare for ImageMagick
Browse files Browse the repository at this point in the history
fix tests that fail on Linux
  • Loading branch information
longlho authored and Long Ho committed Nov 28, 2013
1 parent 3af88a7 commit 66b9316
Show file tree
Hide file tree
Showing 4 changed files with 102 additions and 33 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,4 @@ examples/imgs/*
!examples/imgs/orientation/*\d.jpg
!examples/imgs/orientation/*.correct.jpg
*.sw*
.idea
3 changes: 2 additions & 1 deletion index.js
Original file line number Diff line number Diff line change
Expand Up @@ -115,14 +115,15 @@ require("./lib/args")(gm.prototype);
require("./lib/drawing")(gm.prototype);
require("./lib/convenience")(gm.prototype);
require("./lib/command")(gm.prototype);
require("./lib/compare")(gm.prototype);

/**
* Expose.
*/

module.exports = exports = gm;
module.exports.utils = require('./lib/utils');
module.exports.compare = require('./lib/compare');
module.exports.compare = require('./lib/compare')();
module.exports.version = JSON.parse(
require('fs').readFileSync(__dirname + '/package.json', 'utf8')
).version;
Expand Down
100 changes: 68 additions & 32 deletions lib/compare.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,41 +18,77 @@ var utils = require('./utils');
* @param {Function} cb(err, Boolean, equality, rawOutput)
*/

module.exports = exports = function compare (orig, compareTo, tolerance, cb) {
orig = utils.escape(orig);
compareTo = utils.escape(compareTo);

// outputting the diff image
if (typeof tolerance === 'object') {
var diffOptions = tolerance;
if (typeof diffOptions.file !== 'string') {
throw new TypeError('The path for the diff output is invalid');
}
// graphicsmagick defaults to red
var highlightColorOption = diffOptions.highlightColor
? ' -highlight-color ' + diffOptions.highlightColor + ' '
: ' ';
module.exports = exports = function (proto) {
function compare(orig, compareTo, tolerance, cb) {
orig = utils.escape(orig);
compareTo = utils.escape(compareTo);

return exec('gm compare' + highlightColorOption + orig + ' ' + compareTo +
' -file ' + utils.escape(diffOptions.file), cb);
}
var isImageMagick = this._options && this._options.imageMagick;
var bin = isImageMagick ? '' : 'gm ';

// else, output the mean square error (mse)
if ('function' == typeof tolerance) {
cb = tolerance;
tolerance = 0.4;
}
// outputting the diff image
if (typeof tolerance === 'object') {
var diffOptions = tolerance;
if (typeof diffOptions.file !== 'string') {
throw new TypeError('The path for the diff output is invalid');
}
// graphicsmagick defaults to red
var highlightColorOption = diffOptions.highlightColor
? ' -highlight-color ' + diffOptions.highlightColor + ' '
: ' ';
var diffFilename = utils.escape(diffOptions.file);
var diffOpt = isImageMagick ? diffFilename : ('-file ' + diffFilename);
var cmd = bin + 'compare' + highlightColorOption + orig + ' ' + compareTo +
' ' + diffOpt;

exec('gm compare -metric mse ' + orig + ' ' + compareTo, function (err, stdout, stderr) {
if (err) return cb(err);
return exec(cmd, function (err, stdout, stderr) {
if (isImageMagick && err && err.code === 1) {
err = null;
}
return cb(err, stdout, stderr);
});
}

var match = /Total: (\d+\.?\d*)/m.exec(stdout);
if (!match) {
err = new Error('Unable to parse output.\nGot ' + stdout);
return cb(err);
// else, output the mean square error (mse)
if ('function' == typeof tolerance) {
cb = tolerance;
tolerance = 0.4;
}

var equality = parseFloat(match[1]);
cb(null, equality <= tolerance, equality, stdout);
});
}
var execCmd = bin + 'compare -metric mse ' + orig + ' ' + compareTo;
// For ImageMagick diff file is required but we don't care about it, so null it out
isImageMagick && (execCmd += ' null:');

exec(execCmd, function (err, stdout, stderr) {
// ImageMagick returns err code 2 if err, 0 if similar, 1 if dissimilar
if (isImageMagick) {
if (!err) {
return cb(null, 0 <= tolerance, 0, stdout);
}
if (err.code === 1) {
err = null;
stdout = stderr;
}
}
if (err) {
return cb(err);
}
// Since ImageMagick similar gives err code 0 and no stdout, there's really no matching
var regex = isImageMagick ? /\((\d+\.?\d*)\)/m : /Total: (\d+\.?\d*)/m;
var match = regex.exec(stdout);
if (!match) {
err = new Error('Unable to parse output.\nGot ' + stdout);
return cb(err);
}

var equality = parseFloat(match[1]);
cb(null, equality <= tolerance, equality, stdout);
});
}

if (proto) {
proto.compare = compare;
}
return compare;
};

31 changes: 31 additions & 0 deletions test/compareImageMagick.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
var assert = require('assert');
var fs = require('fs');

module.exports = function (gm, dir, finish, GM) {

// Same image
gm.compare(dir + '/original.jpg', dir + '/original.png', function(err, same) {
if (err) return finish(err);
if (!same) return finish(new Error('Compare should be the same!'));

// Create a new noisy image
gm.noise(0.3).write(dir + '/noise3.png', function (err) {
if (err) return finish(err);

var options = {
highlightColor: 'yellow',
file: dir + '/diff.png'
};

// Compare these images and write to a file.
gm.compare(dir + '/original.jpg', dir + '/noise3.png', options, function(err) {
if (err) return finish(err);

fs.exists(options.file, function(exists) {
if (exists) finish();
else finish(new Error('Diff file does not exist.'));
});
});
})
});
};

0 comments on commit 66b9316

Please sign in to comment.