corrade-nucleus-nucleons – Blame information for rev 36

Subversion Repositories:
Rev:
Rev Author Line No. Line
36 office 1 // compare
2  
3 var spawn = require('cross-spawn');
4  
5 /**
6 * Compare two images uses graphicsmagicks `compare` command.
7 *
8 * gm.compare(img1, img2, 0.4, function (err, equal, equality) {
9 * if (err) return handle(err);
10 * console.log('The images are equal: %s', equal);
11 * console.log('There equality was %d', equality);
12 * });
13 *
14 * @param {String} orig Path to an image.
15 * @param {String} compareTo Path to another image to compare to `orig`.
16 * @param {Number|Object} [options] Options object or the amount of difference to tolerate before failing - defaults to 0.4
17 * @param {Function} cb(err, Boolean, equality, rawOutput)
18 */
19  
20 module.exports = exports = function (proto) {
21 function compare(orig, compareTo, options, cb) {
22  
23 var isImageMagick = this._options && this._options.imageMagick;
24 var appPath = this._options && this._options.appPath || '';
25 var bin = isImageMagick
26 ? appPath + 'compare'
27 : appPath + 'gm'
28 var args = ['-metric', 'mse', orig, compareTo]
29 if (!isImageMagick) {
30 args.unshift('compare');
31 }
32 var tolerance = 0.4;
33 // outputting the diff image
34 if (typeof options === 'object') {
35  
36 if (options.highlightColor && options.highlightColor.indexOf('"') < 0) {
37 options.highlightColor = '"' + options.highlightColor + '"';
38 }
39  
40 if (options.file) {
41 if (typeof options.file !== 'string') {
42 throw new TypeError('The path for the diff output is invalid');
43 }
44 // graphicsmagick defaults to red
45 if (options.highlightColor) {
46 args.push('-highlight-color');
47 args.push(options.highlightColor);
48 }
49 if (options.highlightStyle) {
50 args.push('-highlight-style')
51 args.push(options.highlightStyle)
52 }
53 // For IM, filename is the last argument. For GM it's `-file <filename>`
54 if (!isImageMagick) {
55 args.push('-file');
56 }
57 args.push(options.file);
58 }
59  
60 if (typeof options.tolerance != 'undefined') {
61 if (typeof options.tolerance !== 'number') {
62 throw new TypeError('The tolerance value should be a number');
63 }
64 tolerance = options.tolerance;
65 }
66 } else {
67 // For ImageMagick diff file is required but we don't care about it, so null it out
68 if (isImageMagick) {
69 args.push('null:');
70 }
71  
72 if (typeof options == 'function') {
73 cb = options; // tolerance value not provided, flip the cb place
74 } else {
75 tolerance = options
76 }
77 }
78  
79 var proc = spawn(bin, args);
80 var stdout = '';
81 var stderr = '';
82 proc.stdout.on('data',function(data) { stdout+=data });
83 proc.stderr.on('data',function(data) { stderr+=data });
84 proc.on('close', function (code) {
85 // ImageMagick returns err code 2 if err, 0 if similar, 1 if dissimilar
86 if (isImageMagick) {
87 if (code === 0) {
88 return cb(null, 0 <= tolerance, 0, stdout);
89 }
90 else if (code === 1) {
91 err = null;
92 stdout = stderr;
93 } else {
94 return cb(stderr);
95 }
96 } else {
97 if(code !== 0) {
98 return cb(stderr);
99 }
100 }
101 // Since ImageMagick similar gives err code 0 and no stdout, there's really no matching
102 // Otherwise, output format for IM is `12.00 (0.123)` and for GM it's `Total: 0.123`
103 var regex = isImageMagick ? /\((\d+\.?[\d\-\+e]*)\)/m : /Total: (\d+\.?\d*)/m;
104 var match = regex.exec(stdout);
105 if (!match) {
106 err = new Error('Unable to parse output.\nGot ' + stdout);
107 return cb(err);
108 }
109  
110 var equality = parseFloat(match[1]);
111 cb(null, equality <= tolerance, equality, stdout, orig, compareTo);
112 });
113 }
114  
115 if (proto) {
116 proto.compare = compare;
117 }
118 return compare;
119 };
120