Coder Social home page Coder Social logo

humblesoftware / js-imagediff Goto Github PK

View Code? Open in Web Editor NEW
786.0 24.0 100.0 625 KB

JavaScript / Canvas based image diff utility with Jasmine matchers for testing canvas.

Home Page: http://humblesoftware.github.com/js-imagediff/

License: MIT License

Makefile 0.18% JavaScript 99.82%

js-imagediff's Introduction

js-imagediff

JavaScript / Canvas based imagediff utility.

API

  • createCanvas() create a new Canvas element.
  • createImageData(width, height) create a new ImageData object.
  • isImage(object) tests for Image object.
  • isCanvas(object) tests for Canvas object.
  • isContext(object) tests for CanvasRenderingContext2D object.
  • isImageData(object) tests for ImageData object.
  • isImageType(object) tests for any of the above.
  • toImageData(object) converts image type object to a new ImageData object.
  • equal(a, b, tolerance) tests image type objects for equality; accepts tolerance in pixels.
  • diff(a, b, options) performs an image diff on a and b, returning a - b.
    • options.align set to 'top' to top-align the images when diffing different sizes.
  • noConflict() removes imagediff from the global space for compatibility, returning imagediff.
  • imageDataToPNG(imageData, outputFile, [callback]) (node only) renders the imageData to png in outputFile with optional callback.

NodeJS

js-imagediff is available through the npm. It uses node-canvas which requires lib cairo to be installed. Install js-imagediff with npm install -g imagediff.

Command Line

  • imagediff [-e|equal] [-t|tolerance VALUE] FILE_A FILE_B tests equality of two image files with an optional tolerance, printing 'true' or 'false'.
  • imagediff [-d|diff] FILE_A FILE_B OUTPUT_FILE renders an imagediff between two files, saving as the output file.

Cannot find module 'canvas'

Canvas has been moved to an optional dependency for better browser and browserify support. If you see a message that the module cannot be found, please check npm install first, incase there was indeed an issue installing it. This relates to #22. Please let me know if you have any issues on account of this, or know of a better work around.

Unit Testing Canvas

JS ImageDiff opens up the easy testing of Canvas and other image-like objects in JavaScript. js-imagediff supplies two Jasmine matchers to make this easier.

  • toImageDiffEqual(expected, tolerance) expect a result to equal another image type.
  • toBeImageData() expect a result to be ImageData.

On failed tests, toImageDiffEqual() will display the expected image, the actual image and the imagediff of the two letting you easily spot mistakes.

To use matchers:

  beforeEach(function () {
    this.addMatchers(imagediff.jasmine);
  });

Demo

Users

If you are using js-imagediff pelase drop us a line and let us know what you are doing with it.

Changelog

2.0.0-alpha

* Update to support Jasmine 3.

1.0.8

* Update canvas dependency. * Expose internal Canvas.

1.0.7

* Add async image loading for canvas (closes #31, #35, #39). * Support `--diff`, `--equal`, `--tolerance` (closes #17).

1.0.6

* Add top-aligned diffing option. * Fix issue with diffing transparencies.

1.0.5

* Move canvas to optional dependencies for browserify support.

1.0.4

* Updated canvas dependency. * Add check for arguments count in diff mode.

1.0.3

* Added NPM/node.js support. * Added command line interface for `equal` and `diff` methods. * Added `imageDataToPNG` method for node environments. * Added tolerance to handle lossy formats and provide option for acceptable difference.

1.0.2

* Added optional width / height parameters to `createCanvas` for symmetry with `createImageData`. * Fixed issue with `toImageDiffEqual()` matcher and non Node types - will no convert ImageData and contexts to Canvas elements for display.

1.0.1

* Moved library to imagediff.js * Added Jasmine matchers * Minor bug fixes, lint fixes.

Author

Carl Sutherland [email protected] http://www.humblesoftware.com

js-imagediff's People

Contributors

0xflotus avatar azproduction avatar benkaiser avatar cburgmer avatar cesutherland avatar joostvdoorn avatar jsantell avatar mstefaniuk avatar raphamorim avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

js-imagediff's Issues

Image complete

Test input images to make sure loaded completely.

Can this functionality be added to matchers (does jasmine support async matchers?)

branch v1.1: toImageDiffEqual fails headlessly using jasmine 2.1.3 and phantom

I'm using the v1.1 branch for jasmine 2 support,

my toImageDiffEqual test passes in the browser with jasmine, but not headlessly with jasmine and phantom

Is this because v1.1 is not released yet? and if so, does headless testing plan to be supported with jasmine 2+?

The error is quite vague: see below:

screen shot 2015-02-23 at 17 16 40

Test code:

this.compareImage = function (path, done, expect, pixelTolerance) {
        var stage = this.stage;
        stage.update();
        var img = new Image();
        img.src = path;
        img.onload = function () {
            var pixels = this.width * this.height;
            var tolerance = pixels * (typeof pixelTolerance === 'undefined' ? 0.005 : pixelTolerance);
            expect(stage.canvas).toImageDiffEqual(this, tolerance); //###### < ERROR THROWN #######
            done();
        };
        img.onerror = function () {
            fail(img.src + ' failed to load');
            done();
        };
    };

Image or Canvas expected when using in nodejs

Hi!
I'm trying to get imagediff work in nodejs but with no luck.
My code is pretty simple and looks like https://github.com/HumbleSoftware/js-imagediff/blob/master/bin/imagediff

var fs = require('fs'),
  imagediff = require('imagediff'),
  Canvas = require('canvas');

function loadImage (url, callback) {
  var image = new Canvas.Image();
  fs.readFile(url, function (error, data) {
    if (error) throw error;
    image.onload = function () {
      callback(image);
    };
    image.src = data;
  });
  return image;
}

var aName = 'test.png';

loadImage(aName, function (a) {
  var aData = imagediff.toImageData(a);
  console.log(" >>>>> equal: ", imagediff.equal(aData, aData));
});

But i got an error:

/vagrant/node_modules/imagediff/imagediff.js:126
    context.drawImage(image, 0, 0);
           ^
TypeError: Image or Canvas expected...

I have found related issue #38 but it gave me no new info about the problem.

I'm using:

  • "canvas": "1.2.7"
  • "imagediff": "1.0.8"
  • "node": "0.10.37"

I have tried to run imagediff command line tool and it is working as expected. I also noticed that imagediff uses old version of "canvas" (1.1.6) and have tried to use it in my project but with no success (have the same error).

Thanks for any help.

Feature request: global tolerance value

I have a use case where I'd like to compare images using a global tolerance aka "the images are less than 5% different". So far equal only accounts for a threshold on a per color and pixel value.

The implementation is probably fairly trivial, I'd see the difficulty in finding a meaningful way of integrating that.

Would that feature make sense here?

Faulty diff calculation for transparency

Hey, while looking for something unrelated I stumbled upon this line of code:

cData[i+3] = Math.abs(255 - aData[i+3] - bData[i+3]);

I think what we want is this:

cData[i+3] = Math.abs(255 - Math.abs(aData[i+3] - bData[i+3]));

Error: Image given has not completed loading

I'm getting the following error when running imagediff on the command line.

$ imagediff --diff "file_a.png" "file_b.png" "~/Desktop/file_diff.png"

/usr/local/lib/node_modules/imagediff/imagediff.js:113
    context.drawImage(image, 0, 0);
            ^
Error: Image given has not completed loading
    at toImageDataFromImage (/usr/local/lib/node_modules/imagediff/imagediff.js:113:13)
    at toImageData (/usr/local/lib/node_modules/imagediff/imagediff.js:101:35)
    at Object.imagediff.toImageData (/usr/local/lib/node_modules/imagediff/imagediff.js:352:14)
    at commandLine (/usr/local/lib/node_modules/imagediff/bin/imagediff:47:17)
    at Object.<anonymous> (/usr/local/lib/node_modules/imagediff/bin/imagediff:6:1)
    at Module._compile (module.js:456:26)
    at Object.Module._extensions..js (module.js:474:10)
    at Module.load (module.js:356:32)
    at Function.Module._load (module.js:312:12)
    at Function.Module.runMain (module.js:497:10)
  • OS X 10.8.4
  • Node.js 0.10.17
  • Cairo and dependencies installed from MacPorts
  • Installed via sudo npm install -g imagediff

[Feature request] Ignorable areas

Would it be possible to implement the ability to ignore areas of an image when diff'ing? For example, if I have an image of a web page which I want to compare against a baseline image I might want to ignore certain areas, such as dynamic text or images.

This could be done by specifying rectangle areas to ignore with top left x and y coordinates and bottom right x and y coordinates.

Canvas not found error

I'm not sure whether this is an error on imagediff or it is actually on node-canvas, but I'm getting this using imagediff so this seemed like the right place for this issue. Please let me know if I need to get this to the node-canvas issue tracker.

I installed imagediff both in the global scope (-g) and in my project and I'm getting this error complaining about the canvas (binary?) not being on the folder it expects it to be. I tried rebuilding the canvas binary from imagediff/node_modules/canvas but that doesn't seem to solve anything, and as far as I can tell I'm getting no build errors (unless they are obscurely silent and hidden somewhere).

 [Error: module "../build/Release/canvas" not found from "/Users/uorbe001/Projects/blah/node_modules/imagediff/node_modules/canvas/lib/bindings.js"]
Error: module "../build/Release/canvas" not found from "/Users/uorbe001/Projects/blah/node_modules/imagediff/node_modules/canvas/lib/bindings.js"
    at /Users/uorbe001/Projects/blah/node_modules/karma-browserify/node_modules/browserify/index.js:354:30
    at /Users/uorbe001/Projects/blah/node_modules/karma-browserify/node_modules/browserify/node_modules/browser-resolve/index.js:179:17
    at /Users/uorbe001/Projects/blah/node_modules/karma-browserify/node_modules/browserify/node_modules/browser-resolve/node_modules/resolve/lib/async.js:37:22
    at load (/Users/uorbe001/Projects/blah/node_modules/karma-browserify/node_modules/browserify/node_modules/browser-resolve/node_modules/resolve/lib/async.js:54:43)
    at /Users/uorbe001/Projects/blah/node_modules/karma-browserify/node_modules/browserify/node_modules/browser-resolve/node_modules/resolve/lib/async.js:60:22
    at /Users/uorbe001/Projects/blah/node_modules/karma-browserify/node_modules/browserify/node_modules/browser-resolve/node_modules/resolve/lib/async.js:16:47
    at Object.oncomplete (fs.js:107:15)

Weird thing is, unless I'm mistaken, the canvas it's trying to load is on the folder it is searching, because running ls node_modules/imagediff/node_modules/canvas/build/Release returns canvas.node linker.lock obj.target. Any ideas about what I'm doing wrong?

Installation error with node v8.9.3

Running on a macbook pro with Sierra (10.12.6):

$ npm install -g imagediff

Result:

../../nan/nan.h:342:68: error: too many arguments to function call, expected at most 2, have 4
    return v8::Signature::New(v8::Isolate::GetCurrent(), receiver, argc, argv);
           ~~~~~~~~~~~~~~~~~~                                      ^~~~~~~~~~
/Users/scottj/.node-gyp/8.9.3/include/node/v8.h:5871:3: note: 'New' declared here
  static Local<Signature> New(
  ^
In file included from ../src/Canvas.cc:7:
In file included from ../src/Canvas.h:22:
../../nan/nan.h:397:32: warning: 'CompileUnbound' is deprecated [-Wdeprecated-declarations]
    return v8::ScriptCompiler::CompileUnbound(
                               ^
/Users/scottj/.node-gyp/8.9.3/include/node/v8.h:1403:10: note: 'CompileUnbound' has been explicitly marked deprecated here
  static V8_DEPRECATED("Use maybe version",
         ^
/Users/scottj/.node-gyp/8.9.3/include/node/v8config.h:321:29: note: expanded from macro 'V8_DEPRECATED'
  declarator __attribute__((deprecated))
                            ^
In file included from ../src/Canvas.cc:7:
In file included from ../src/Canvas.h:22:
../../nan/nan.h:406:32: warning: 'CompileUnbound' is deprecated [-Wdeprecated-declarations]
    return v8::ScriptCompiler::CompileUnbound(
                               ^
/Users/scottj/.node-gyp/8.9.3/include/node/v8.h:1403:10: note: 'CompileUnbound' has been explicitly marked deprecated here
  static V8_DEPRECATED("Use maybe version",
         ^
/Users/scottj/.node-gyp/8.9.3/include/node/v8config.h:321:29: note: expanded from macro 'V8_DEPRECATED'
  declarator __attribute__((deprecated))
                            ^
In file included from ../src/Canvas.cc:7:
In file included from ../src/Canvas.h:22:
../../nan/nan.h:412:31: warning: 'New' is deprecated [-Wdeprecated-declarations]
    return v8::BooleanObject::New(value).As<v8::BooleanObject>();
                              ^
/Users/scottj/.node-gyp/8.9.3/include/node/v8.h:4793:3: note: 'New' has been explicitly marked deprecated here
  V8_DEPRECATED("Pass an isolate", static Local<Value> New(bool value));
  ^
/Users/scottj/.node-gyp/8.9.3/include/node/v8config.h:321:29: note: expanded from macro 'V8_DEPRECATED'
  declarator __attribute__((deprecated))
                            ^
In file included from ../src/Canvas.cc:7:
In file included from ../src/Canvas.h:22:
../../nan/nan.h:424:3: error: redefinition of 'NanNew'
  NanNew<v8::StringObject, v8::Handle<v8::String> >(
  ^
../../nan/nan.h:417:3: note: previous definition is here
  NanNew<v8::StringObject, v8::Local<v8::String> >(
  ^
../../nan/nan.h:442:36: error: redefinition of 'NanNew'
  NAN_INLINE v8::Local<v8::RegExp> NanNew(
                                   ^
../../nan/nan.h:436:36: note: previous definition is here
  NAN_INLINE v8::Local<v8::RegExp> NanNew(
                                   ^
../../nan/nan.h:454:36: error: redefinition of 'NanNew'
  NAN_INLINE v8::Local<v8::RegExp> NanNew(
                                   ^
../../nan/nan.h:448:36: note: previous definition is here
  NAN_INLINE v8::Local<v8::RegExp> NanNew(
                                   ^
../../nan/nan.h:462:42: warning: 'ToUint32' is deprecated [-Wdeprecated-declarations]
        v8::Isolate::GetCurrent(), val)->ToUint32();
                                         ^
/Users/scottj/.node-gyp/8.9.3/include/node/v8.h:2330:10: note: 'ToUint32' has been explicitly marked deprecated here
  inline V8_DEPRECATED("Use maybe version", Local<Uint32> ToUint32() const);
         ^
/Users/scottj/.node-gyp/8.9.3/include/node/v8config.h:321:29: note: expanded from macro 'V8_DEPRECATED'
  declarator __attribute__((deprecated))
                            ^
In file included from ../src/Canvas.cc:7:
In file included from ../src/Canvas.h:22:
../../nan/nan.h:468:42: warning: 'ToUint32' is deprecated [-Wdeprecated-declarations]
        v8::Isolate::GetCurrent(), val)->ToUint32();
                                         ^
/Users/scottj/.node-gyp/8.9.3/include/node/v8.h:2330:10: note: 'ToUint32' has been explicitly marked deprecated here
  inline V8_DEPRECATED("Use maybe version", Local<Uint32> ToUint32() const);
         ^
/Users/scottj/.node-gyp/8.9.3/include/node/v8config.h:321:29: note: expanded from macro 'V8_DEPRECATED'
  declarator __attribute__((deprecated))
                            ^
In file included from ../src/Canvas.cc:7:
In file included from ../src/Canvas.h:22:
../../nan/nan.h:473:60: warning: 'ToInt32' is deprecated [-Wdeprecated-declarations]
    return v8::Int32::New(v8::Isolate::GetCurrent(), val)->ToInt32();
                                                           ^
/Users/scottj/.node-gyp/8.9.3/include/node/v8.h:2331:10: note: 'ToInt32' has been explicitly marked deprecated here
  inline V8_DEPRECATED("Use maybe version", Local<Int32> ToInt32() const);
         ^
/Users/scottj/.node-gyp/8.9.3/include/node/v8config.h:321:29: note: expanded from macro 'V8_DEPRECATED'
  declarator __attribute__((deprecated))
                            ^
In file included from ../src/Canvas.cc:7:
In file included from ../src/Canvas.h:22:
../../nan/nan.h:478:60: warning: 'ToInt32' is deprecated [-Wdeprecated-declarations]
    return v8::Int32::New(v8::Isolate::GetCurrent(), val)->ToInt32();
                                                           ^
/Users/scottj/.node-gyp/8.9.3/include/node/v8.h:2331:10: note: 'ToInt32' has been explicitly marked deprecated here
  inline V8_DEPRECATED("Use maybe version", Local<Int32> ToInt32() const);
         ^
/Users/scottj/.node-gyp/8.9.3/include/node/v8config.h:321:29: note: expanded from macro 'V8_DEPRECATED'
  declarator __attribute__((deprecated))
                            ^
In file included from ../src/Canvas.cc:7:
In file included from ../src/Canvas.h:22:
../../nan/nan.h:518:24: warning: 'NewFromOneByte' is deprecated [-Wdeprecated-declarations]
    return v8::String::NewFromOneByte(
                       ^
/Users/scottj/.node-gyp/8.9.3/include/node/v8.h:2668:10: note: 'NewFromOneByte' has been explicitly marked deprecated here
  static V8_DEPRECATED(
         ^
/Users/scottj/.node-gyp/8.9.3/include/node/v8config.h:321:29: note: expanded from macro 'V8_DEPRECATED'
  declarator __attribute__((deprecated))
                            ^
In file included from ../src/Canvas.cc:7:
In file included from ../src/Canvas.h:22:
../../nan/nan.h:529:24: warning: 'NewFromOneByte' is deprecated [-Wdeprecated-declarations]
    return v8::String::NewFromOneByte(
                       ^
/Users/scottj/.node-gyp/8.9.3/include/node/v8.h:2668:10: note: 'NewFromOneByte' has been explicitly marked deprecated here
  static V8_DEPRECATED(
         ^
/Users/scottj/.node-gyp/8.9.3/include/node/v8config.h:321:29: note: expanded from macro 'V8_DEPRECATED'
  declarator __attribute__((deprecated))
                            ^
In file included from ../src/Canvas.cc:7:
In file included from ../src/Canvas.h:22:
../../nan/nan.h:538:24: warning: 'NewFromOneByte' is deprecated [-Wdeprecated-declarations]
    return v8::String::NewFromOneByte(v8::Isolate::GetCurrent(), arg);
                       ^
/Users/scottj/.node-gyp/8.9.3/include/node/v8.h:2668:10: note: 'NewFromOneByte' has been explicitly marked deprecated here
  static V8_DEPRECATED(
         ^
/Users/scottj/.node-gyp/8.9.3/include/node/v8config.h:321:29: note: expanded from macro 'V8_DEPRECATED'
  declarator __attribute__((deprecated))
                            ^
In file included from ../src/Canvas.cc:7:
In file included from ../src/Canvas.h:22:
../../nan/nan.h:544:24: warning: 'NewFromOneByte' is deprecated [-Wdeprecated-declarations]
    return v8::String::NewFromOneByte(v8::Isolate::GetCurrent(), arg);
                       ^
/Users/scottj/.node-gyp/8.9.3/include/node/v8.h:2668:10: note: 'NewFromOneByte' has been explicitly marked deprecated here
  static V8_DEPRECATED(
         ^
/Users/scottj/.node-gyp/8.9.3/include/node/v8config.h:321:29: note: expanded from macro 'V8_DEPRECATED'
  declarator __attribute__((deprecated))
                            ^
In file included from ../src/Canvas.cc:7:
In file included from ../src/Canvas.h:22:
../../nan/nan.h:619:24: warning: 'NewExternal' is deprecated [-Wdeprecated-declarations]
    return v8::String::NewExternal(v8::Isolate::GetCurrent(), resource);
                       ^
/Users/scottj/.node-gyp/8.9.3/include/node/v8.h:2707:10: note: 'NewExternal' has been explicitly marked deprecated here
  static V8_DEPRECATED("Use maybe version",
         ^
/Users/scottj/.node-gyp/8.9.3/include/node/v8config.h:321:29: note: expanded from macro 'V8_DEPRECATED'
  declarator __attribute__((deprecated))
                            ^
In file included from ../src/Canvas.cc:7:
In file included from ../src/Canvas.h:22:
../../nan/nan.h:623:19: error: no type named 'ExternalAsciiStringResource' in 'v8::String'; did you mean 'ExternalStringResource'?
      v8::String::ExternalAsciiStringResource *resource) {
      ~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~
                  ExternalStringResource
/Users/scottj/.node-gyp/8.9.3/include/node/v8.h:2577:19: note: 'ExternalStringResource' declared here
  class V8_EXPORT ExternalStringResource
                  ^
In file included from ../src/Canvas.cc:7:
In file included from ../src/Canvas.h:22:
../../nan/nan.h:622:36: error: redefinition of 'NanNew'
  NAN_INLINE v8::Local<v8::String> NanNew(
                                   ^
../../nan/nan.h:617:36: note: previous definition is here
  NAN_INLINE v8::Local<v8::String> NanNew(
                                   ^
../../nan/nan.h:624:24: warning: 'NewExternal' is deprecated [-Wdeprecated-declarations]
    return v8::String::NewExternal(v8::Isolate::GetCurrent(), resource);
                       ^
/Users/scottj/.node-gyp/8.9.3/include/node/v8.h:2707:10: note: 'NewExternal' has been explicitly marked deprecated here
  static V8_DEPRECATED("Use maybe version",
         ^
/Users/scottj/.node-gyp/8.9.3/include/node/v8config.h:321:29: note: expanded from macro 'V8_DEPRECATED'
  declarator __attribute__((deprecated))
                            ^
In file included from ../src/Canvas.cc:7:
In file included from ../src/Canvas.h:22:
../../nan/nan.h:637:27: error: redefinition of '_NanEscapeScopeHelper'
  NAN_INLINE v8::Local<T> _NanEscapeScopeHelper(v8::Local<T> val) {
                          ^
../../nan/nan.h:632:27: note: previous definition is here
  NAN_INLINE v8::Local<T> _NanEscapeScopeHelper(v8::Handle<T> val) {
                          ^
../../nan/nan.h:653:12: error: no matching function for call to '_NanEscapeScopeHelper'
    return NanEscapeScope(NanNew(v8::Undefined(v8::Isolate::GetCurrent())));
           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
../../nan/nan.h:641:43: note: expanded from macro 'NanEscapeScope'
# define NanEscapeScope(val) scope.Escape(_NanEscapeScopeHelper(val))
                                          ^~~~~~~~~~~~~~~~~~~~~
../../nan/nan.h:637:27: note: candidate template ignored: substitution failure [with T = v8::Primitive]
  NAN_INLINE v8::Local<T> _NanEscapeScopeHelper(v8::Local<T> val) {
                          ^
../../nan/nan.h:658:12: error: no matching function for call to '_NanEscapeScopeHelper'
    return NanEscapeScope(NanNew(v8::Null(v8::Isolate::GetCurrent())));
           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
../../nan/nan.h:641:43: note: expanded from macro 'NanEscapeScope'
# define NanEscapeScope(val) scope.Escape(_NanEscapeScopeHelper(val))
                                          ^~~~~~~~~~~~~~~~~~~~~
../../nan/nan.h:637:27: note: candidate template ignored: substitution failure [with T = v8::Primitive]
  NAN_INLINE v8::Local<T> _NanEscapeScopeHelper(v8::Local<T> val) {
                          ^
../../nan/nan.h:663:12: error: no matching function for call to '_NanEscapeScopeHelper'
    return NanEscapeScope(NanNew(v8::True(v8::Isolate::GetCurrent())));
           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
../../nan/nan.h:641:43: note: expanded from macro 'NanEscapeScope'
# define NanEscapeScope(val) scope.Escape(_NanEscapeScopeHelper(val))
                                          ^~~~~~~~~~~~~~~~~~~~~
../../nan/nan.h:637:27: note: candidate template ignored: substitution failure [with T = v8::Boolean]
  NAN_INLINE v8::Local<T> _NanEscapeScopeHelper(v8::Local<T> val) {
                          ^
../../nan/nan.h:668:12: error: no matching function for call to '_NanEscapeScopeHelper'
    return NanEscapeScope(NanNew(v8::False(v8::Isolate::GetCurrent())));
           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
../../nan/nan.h:641:43: note: expanded from macro 'NanEscapeScope'
# define NanEscapeScope(val) scope.Escape(_NanEscapeScopeHelper(val))
                                          ^~~~~~~~~~~~~~~~~~~~~
../../nan/nan.h:637:27: note: candidate template ignored: substitution failure [with T = v8::Boolean]
  NAN_INLINE v8::Local<T> _NanEscapeScopeHelper(v8::Local<T> val) {
                          ^
../../nan/nan.h:701:20: error: no type named 'GCEpilogueCallback' in 'v8::Isolate'
      v8::Isolate::GCEpilogueCallback callback
      ~~~~~~~~~~~~~^
../../nan/nan.h:707:20: error: no type named 'GCEpilogueCallback' in 'v8::Isolate'
      v8::Isolate::GCEpilogueCallback callback) {
      ~~~~~~~~~~~~~^
../../nan/nan.h:712:20: error: no type named 'GCPrologueCallback' in 'v8::Isolate'
      v8::Isolate::GCPrologueCallback callback
      ~~~~~~~~~~~~~^
../../nan/nan.h:718:20: error: no type named 'GCPrologueCallback' in 'v8::Isolate'
      v8::Isolate::GCPrologueCallback callback) {
      ~~~~~~~~~~~~~^
../../nan/nan.h:797:15: error: no type named 'WeakCallbackData' in namespace 'v8'
    const v8::WeakCallbackData<T, _NanWeakCallbackInfo<T, P> > &data) {
          ~~~~^
../../nan/nan.h:797:31: error: expected ')'
    const v8::WeakCallbackData<T, _NanWeakCallbackInfo<T, P> > &data) {
                              ^
../../nan/nan.h:796:41: note: to match this '('
  static void _NanWeakCallbackDispatcher(
                                        ^
../../nan/nan.h:798:42: error: use of undeclared identifier 'data'
      _NanWeakCallbackInfo<T, P> *info = data.GetParameter();
                                         ^
../../nan/nan.h:889:13: error: no member named 'smalloc' in namespace 'node'
    , node::smalloc::FreeCallback callback
      ~~~~~~^
fatal error: too many errors emitted, stopping now [-ferror-limit=]
13 warnings and 20 errors generated.
make: *** [Release/obj.target/canvas/src/Canvas.o] Error 1
gyp ERR! build error
gyp ERR! stack Error: `make` failed with exit code: 2
gyp ERR! stack     at ChildProcess.onExit (/Users/scottj/.nvm/versions/node/v8.9.3/lib/node_modules/npm/node_modules/node-gyp/lib/build.js:258:23)
gyp ERR! stack     at emitTwo (events.js:126:13)
gyp ERR! stack     at ChildProcess.emit (events.js:214:7)
gyp ERR! stack     at Process.ChildProcess._handle.onexit (internal/child_process.js:198:12)
gyp ERR! System Darwin 16.7.0
gyp ERR! command "/Users/scottj/.nvm/versions/node/v8.9.3/bin/node" "/Users/scottj/.nvm/versions/node/v8.9.3/lib/node_modules/npm/node_modules/node-gyp/bin/node-gyp.js" "rebuild"
gyp ERR! cwd /Users/scottj/.nvm/versions/node/v8.9.3/lib/node_modules/imagediff/node_modules/canvas
gyp ERR! node -v v8.9.3
gyp ERR! node-gyp -v v3.6.2
gyp ERR! not ok
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: [email protected] (node_modules/imagediff/node_modules/canvas):
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: [email protected] install: `node-gyp rebuild`
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: Exit status 1

$ nvm list

Result:

        v6.11.2
         v7.9.0
         v8.4.0
->       v8.9.3
         v9.0.0
default -> v6.11.2
node -> stable (-> v9.0.0) (default)
stable -> 9.0 (-> v9.0.0) (default)
iojs -> N/A (default)
lts/* -> lts/carbon (-> v8.9.3)
lts/argon -> v4.8.7 (-> N/A)
lts/boron -> v6.12.2 (-> N/A)
lts/carbon -> v8.9.3

Note that if I change back to v6.11.2 (the previous version I was using, before attempting to resolve this issue with a newer node module), I get the following error instead:

$ npm install --save-dev imagediff

> [email protected] install /Users/scottj/Source/loop-renderer/node_modules/canvas
> node-gyp rebuild

xcode-select: error: tool 'xcodebuild' requires Xcode, but active developer directory '/Library/Developer/CommandLineTools' is a command line tools instance

xcode-select: error: tool 'xcodebuild' requires Xcode, but active developer directory '/Library/Developer/CommandLineTools' is a command line tools instance

  SOLINK_MODULE(target) Release/canvas-postbuild.node
clang: warning: libstdc++ is deprecated; move to libc++ with a minimum deployment target of OS X 10.9 [-Wdeprecated]
  CXX(target) Release/obj.target/canvas/src/Canvas.o
In file included from ../src/Canvas.cc:7:
In file included from ../src/Canvas.h:22:
../../nan/nan.h:342:68: error: too many arguments to function call, expected at most 2, have 4
    return v8::Signature::New(v8::Isolate::GetCurrent(), receiver, argc, argv);
           ~~~~~~~~~~~~~~~~~~                                      ^~~~~~~~~~
/Users/scottj/.node-gyp/6.11.2/include/node/v8.h:4834:3: note: 'New' declared here
  static Local<Signature> New(
  ^
In file included from ../src/Canvas.cc:7:
In file included from ../src/Canvas.h:22:
../../nan/nan.h:397:32: warning: 'CompileUnbound' is deprecated [-Wdeprecated-declarations]
    return v8::ScriptCompiler::CompileUnbound(
                               ^
/Users/scottj/.node-gyp/6.11.2/include/node/v8.h:1333:10: note: 'CompileUnbound' has been explicitly marked deprecated here
  static V8_DEPRECATED("Use maybe version",
         ^
/Users/scottj/.node-gyp/6.11.2/include/node/v8config.h:336:29: note: expanded from macro 'V8_DEPRECATED'
  declarator __attribute__((deprecated))
                            ^
In file included from ../src/Canvas.cc:7:
In file included from ../src/Canvas.h:22:
../../nan/nan.h:406:32: warning: 'CompileUnbound' is deprecated [-Wdeprecated-declarations]
    return v8::ScriptCompiler::CompileUnbound(
                               ^
/Users/scottj/.node-gyp/6.11.2/include/node/v8.h:1333:10: note: 'CompileUnbound' has been explicitly marked deprecated here
  static V8_DEPRECATED("Use maybe version",
         ^
/Users/scottj/.node-gyp/6.11.2/include/node/v8config.h:336:29: note: expanded from macro 'V8_DEPRECATED'
  declarator __attribute__((deprecated))
                            ^
In file included from ../src/Canvas.cc:7:
In file included from ../src/Canvas.h:22:
../../nan/nan.h:412:31: warning: 'New' is deprecated [-Wdeprecated-declarations]
    return v8::BooleanObject::New(value).As<v8::BooleanObject>();
                              ^
/Users/scottj/.node-gyp/6.11.2/include/node/v8.h:4009:3: note: 'New' has been explicitly marked deprecated here
  V8_DEPRECATED("Pass an isolate", static Local<Value> New(bool value));
  ^
/Users/scottj/.node-gyp/6.11.2/include/node/v8config.h:336:29: note: expanded from macro 'V8_DEPRECATED'
  declarator __attribute__((deprecated))
                            ^
In file included from ../src/Canvas.cc:7:
In file included from ../src/Canvas.h:22:
../../nan/nan.h:424:3: error: redefinition of 'NanNew'
  NanNew<v8::StringObject, v8::Handle<v8::String> >(
  ^
../../nan/nan.h:417:3: note: previous definition is here
  NanNew<v8::StringObject, v8::Local<v8::String> >(
  ^
../../nan/nan.h:442:36: error: redefinition of 'NanNew'
  NAN_INLINE v8::Local<v8::RegExp> NanNew(
                                   ^
../../nan/nan.h:436:36: note: previous definition is here
  NAN_INLINE v8::Local<v8::RegExp> NanNew(
                                   ^
../../nan/nan.h:454:36: error: redefinition of 'NanNew'
  NAN_INLINE v8::Local<v8::RegExp> NanNew(
                                   ^
../../nan/nan.h:448:36: note: previous definition is here
  NAN_INLINE v8::Local<v8::RegExp> NanNew(
                                   ^
../../nan/nan.h:462:42: warning: 'ToUint32' is deprecated [-Wdeprecated-declarations]
        v8::Isolate::GetCurrent(), val)->ToUint32();
                                         ^
/Users/scottj/.node-gyp/6.11.2/include/node/v8.h:2019:10: note: 'ToUint32' has been explicitly marked deprecated here
  inline V8_DEPRECATED("Use maybe version", Local<Uint32> ToUint32() const);
         ^
/Users/scottj/.node-gyp/6.11.2/include/node/v8config.h:336:29: note: expanded from macro 'V8_DEPRECATED'
  declarator __attribute__((deprecated))
                            ^
In file included from ../src/Canvas.cc:7:
In file included from ../src/Canvas.h:22:
../../nan/nan.h:468:42: warning: 'ToUint32' is deprecated [-Wdeprecated-declarations]
        v8::Isolate::GetCurrent(), val)->ToUint32();
                                         ^
/Users/scottj/.node-gyp/6.11.2/include/node/v8.h:2019:10: note: 'ToUint32' has been explicitly marked deprecated here
  inline V8_DEPRECATED("Use maybe version", Local<Uint32> ToUint32() const);
         ^
/Users/scottj/.node-gyp/6.11.2/include/node/v8config.h:336:29: note: expanded from macro 'V8_DEPRECATED'
  declarator __attribute__((deprecated))
                            ^
In file included from ../src/Canvas.cc:7:
In file included from ../src/Canvas.h:22:
../../nan/nan.h:473:60: warning: 'ToInt32' is deprecated [-Wdeprecated-declarations]
    return v8::Int32::New(v8::Isolate::GetCurrent(), val)->ToInt32();
                                                           ^
/Users/scottj/.node-gyp/6.11.2/include/node/v8.h:2020:10: note: 'ToInt32' has been explicitly marked deprecated here
  inline V8_DEPRECATED("Use maybe version", Local<Int32> ToInt32() const);
         ^
/Users/scottj/.node-gyp/6.11.2/include/node/v8config.h:336:29: note: expanded from macro 'V8_DEPRECATED'
  declarator __attribute__((deprecated))
                            ^
In file included from ../src/Canvas.cc:7:
In file included from ../src/Canvas.h:22:
../../nan/nan.h:478:60: warning: 'ToInt32' is deprecated [-Wdeprecated-declarations]
    return v8::Int32::New(v8::Isolate::GetCurrent(), val)->ToInt32();
                                                           ^
/Users/scottj/.node-gyp/6.11.2/include/node/v8.h:2020:10: note: 'ToInt32' has been explicitly marked deprecated here
  inline V8_DEPRECATED("Use maybe version", Local<Int32> ToInt32() const);
         ^
/Users/scottj/.node-gyp/6.11.2/include/node/v8config.h:336:29: note: expanded from macro 'V8_DEPRECATED'
  declarator __attribute__((deprecated))
                            ^
In file included from ../src/Canvas.cc:7:
In file included from ../src/Canvas.h:22:
../../nan/nan.h:518:24: warning: 'NewFromOneByte' is deprecated [-Wdeprecated-declarations]
    return v8::String::NewFromOneByte(
                       ^
/Users/scottj/.node-gyp/6.11.2/include/node/v8.h:2332:10: note: 'NewFromOneByte' has been explicitly marked deprecated here
  static V8_DEPRECATED(
         ^
/Users/scottj/.node-gyp/6.11.2/include/node/v8config.h:336:29: note: expanded from macro 'V8_DEPRECATED'
  declarator __attribute__((deprecated))
                            ^
In file included from ../src/Canvas.cc:7:
In file included from ../src/Canvas.h:22:
../../nan/nan.h:529:24: warning: 'NewFromOneByte' is deprecated [-Wdeprecated-declarations]
    return v8::String::NewFromOneByte(
                       ^
/Users/scottj/.node-gyp/6.11.2/include/node/v8.h:2332:10: note: 'NewFromOneByte' has been explicitly marked deprecated here
  static V8_DEPRECATED(
         ^
/Users/scottj/.node-gyp/6.11.2/include/node/v8config.h:336:29: note: expanded from macro 'V8_DEPRECATED'
  declarator __attribute__((deprecated))
                            ^
In file included from ../src/Canvas.cc:7:
In file included from ../src/Canvas.h:22:
../../nan/nan.h:538:24: warning: 'NewFromOneByte' is deprecated [-Wdeprecated-declarations]
    return v8::String::NewFromOneByte(v8::Isolate::GetCurrent(), arg);
                       ^
/Users/scottj/.node-gyp/6.11.2/include/node/v8.h:2332:10: note: 'NewFromOneByte' has been explicitly marked deprecated here
  static V8_DEPRECATED(
         ^
/Users/scottj/.node-gyp/6.11.2/include/node/v8config.h:336:29: note: expanded from macro 'V8_DEPRECATED'
  declarator __attribute__((deprecated))
                            ^
In file included from ../src/Canvas.cc:7:
In file included from ../src/Canvas.h:22:
../../nan/nan.h:544:24: warning: 'NewFromOneByte' is deprecated [-Wdeprecated-declarations]
    return v8::String::NewFromOneByte(v8::Isolate::GetCurrent(), arg);
                       ^
/Users/scottj/.node-gyp/6.11.2/include/node/v8.h:2332:10: note: 'NewFromOneByte' has been explicitly marked deprecated here
  static V8_DEPRECATED(
         ^
/Users/scottj/.node-gyp/6.11.2/include/node/v8config.h:336:29: note: expanded from macro 'V8_DEPRECATED'
  declarator __attribute__((deprecated))
                            ^
In file included from ../src/Canvas.cc:7:
In file included from ../src/Canvas.h:22:
../../nan/nan.h:619:24: warning: 'NewExternal' is deprecated [-Wdeprecated-declarations]
    return v8::String::NewExternal(v8::Isolate::GetCurrent(), resource);
                       ^
/Users/scottj/.node-gyp/6.11.2/include/node/v8.h:2371:10: note: 'NewExternal' has been explicitly marked deprecated here
  static V8_DEPRECATED("Use maybe version",
         ^
/Users/scottj/.node-gyp/6.11.2/include/node/v8config.h:336:29: note: expanded from macro 'V8_DEPRECATED'
  declarator __attribute__((deprecated))
                            ^
In file included from ../src/Canvas.cc:7:
In file included from ../src/Canvas.h:22:
../../nan/nan.h:623:19: error: no type named 'ExternalAsciiStringResource' in 'v8::String'; did you mean 'ExternalStringResource'?
      v8::String::ExternalAsciiStringResource *resource) {
      ~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~
                  ExternalStringResource
/Users/scottj/.node-gyp/6.11.2/include/node/v8.h:2241:19: note: 'ExternalStringResource' declared here
  class V8_EXPORT ExternalStringResource
                  ^
In file included from ../src/Canvas.cc:7:
In file included from ../src/Canvas.h:22:
../../nan/nan.h:622:36: error: redefinition of 'NanNew'
  NAN_INLINE v8::Local<v8::String> NanNew(
                                   ^
../../nan/nan.h:617:36: note: previous definition is here
  NAN_INLINE v8::Local<v8::String> NanNew(
                                   ^
../../nan/nan.h:624:24: warning: 'NewExternal' is deprecated [-Wdeprecated-declarations]
    return v8::String::NewExternal(v8::Isolate::GetCurrent(), resource);
                       ^
/Users/scottj/.node-gyp/6.11.2/include/node/v8.h:2371:10: note: 'NewExternal' has been explicitly marked deprecated here
  static V8_DEPRECATED("Use maybe version",
         ^
/Users/scottj/.node-gyp/6.11.2/include/node/v8config.h:336:29: note: expanded from macro 'V8_DEPRECATED'
  declarator __attribute__((deprecated))
                            ^
In file included from ../src/Canvas.cc:7:
In file included from ../src/Canvas.h:22:
../../nan/nan.h:637:27: error: redefinition of '_NanEscapeScopeHelper'
  NAN_INLINE v8::Local<T> _NanEscapeScopeHelper(v8::Local<T> val) {
                          ^
../../nan/nan.h:632:27: note: previous definition is here
  NAN_INLINE v8::Local<T> _NanEscapeScopeHelper(v8::Handle<T> val) {
                          ^
../../nan/nan.h:653:12: error: no matching function for call to '_NanEscapeScopeHelper'
    return NanEscapeScope(NanNew(v8::Undefined(v8::Isolate::GetCurrent())));
           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
../../nan/nan.h:641:43: note: expanded from macro 'NanEscapeScope'
# define NanEscapeScope(val) scope.Escape(_NanEscapeScopeHelper(val))
                                          ^~~~~~~~~~~~~~~~~~~~~
../../nan/nan.h:637:27: note: candidate template ignored: substitution failure [with T = v8::Primitive]
  NAN_INLINE v8::Local<T> _NanEscapeScopeHelper(v8::Local<T> val) {
                          ^
../../nan/nan.h:658:12: error: no matching function for call to '_NanEscapeScopeHelper'
    return NanEscapeScope(NanNew(v8::Null(v8::Isolate::GetCurrent())));
           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
../../nan/nan.h:641:43: note: expanded from macro 'NanEscapeScope'
# define NanEscapeScope(val) scope.Escape(_NanEscapeScopeHelper(val))
                                          ^~~~~~~~~~~~~~~~~~~~~
../../nan/nan.h:637:27: note: candidate template ignored: substitution failure [with T = v8::Primitive]
  NAN_INLINE v8::Local<T> _NanEscapeScopeHelper(v8::Local<T> val) {
                          ^
../../nan/nan.h:663:12: error: no matching function for call to '_NanEscapeScopeHelper'
    return NanEscapeScope(NanNew(v8::True(v8::Isolate::GetCurrent())));
           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
../../nan/nan.h:641:43: note: expanded from macro 'NanEscapeScope'
# define NanEscapeScope(val) scope.Escape(_NanEscapeScopeHelper(val))
                                          ^~~~~~~~~~~~~~~~~~~~~
../../nan/nan.h:637:27: note: candidate template ignored: substitution failure [with T = v8::Boolean]
  NAN_INLINE v8::Local<T> _NanEscapeScopeHelper(v8::Local<T> val) {
                          ^
../../nan/nan.h:668:12: error: no matching function for call to '_NanEscapeScopeHelper'
    return NanEscapeScope(NanNew(v8::False(v8::Isolate::GetCurrent())));
           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
../../nan/nan.h:641:43: note: expanded from macro 'NanEscapeScope'
# define NanEscapeScope(val) scope.Escape(_NanEscapeScopeHelper(val))
                                          ^~~~~~~~~~~~~~~~~~~~~
../../nan/nan.h:637:27: note: candidate template ignored: substitution failure [with T = v8::Boolean]
  NAN_INLINE v8::Local<T> _NanEscapeScopeHelper(v8::Local<T> val) {
                          ^
../../nan/nan.h:701:20: error: no type named 'GCEpilogueCallback' in 'v8::Isolate'
      v8::Isolate::GCEpilogueCallback callback
      ~~~~~~~~~~~~~^
../../nan/nan.h:707:20: error: no type named 'GCEpilogueCallback' in 'v8::Isolate'
      v8::Isolate::GCEpilogueCallback callback) {
      ~~~~~~~~~~~~~^
../../nan/nan.h:712:20: error: no type named 'GCPrologueCallback' in 'v8::Isolate'
      v8::Isolate::GCPrologueCallback callback
      ~~~~~~~~~~~~~^
../../nan/nan.h:718:20: error: no type named 'GCPrologueCallback' in 'v8::Isolate'
      v8::Isolate::GCPrologueCallback callback) {
      ~~~~~~~~~~~~~^
../../nan/nan.h:889:13: error: no member named 'smalloc' in namespace 'node'
    , node::smalloc::FreeCallback callback
      ~~~~~~^
../../nan/nan.h:900:12: error: no matching function for call to 'New'
    return node::Buffer::New(v8::Isolate::GetCurrent(), data, size);
           ^~~~~~~~~~~~~~~~~
/Users/scottj/.node-gyp/6.11.2/include/node/node_buffer.h:46:40: note: candidate function not viable: 2nd argument ('const char *') would lose const
      qualifier
NODE_EXTERN v8::MaybeLocal<v8::Object> New(v8::Isolate* isolate,
                                       ^
/Users/scottj/.node-gyp/6.11.2/include/node/node_buffer.h:34:40: note: candidate function not viable: no known conversion from 'const char *' to
      'v8::Local<v8::String>' for 2nd argument
NODE_EXTERN v8::MaybeLocal<v8::Object> New(v8::Isolate* isolate,
                                       ^
/Users/scottj/.node-gyp/6.11.2/include/node/node_buffer.h:31:40: note: candidate function not viable: requires 2 arguments, but 3 were provided
NODE_EXTERN v8::MaybeLocal<v8::Object> New(v8::Isolate* isolate, size_t length);
                                       ^
/Users/scottj/.node-gyp/6.11.2/include/node/node_buffer.h:39:40: note: candidate function not viable: requires 5 arguments, but 3 were provided
NODE_EXTERN v8::MaybeLocal<v8::Object> New(v8::Isolate* isolate,
                                       ^
In file included from ../src/Canvas.cc:7:
In file included from ../src/Canvas.h:22:
../../nan/nan.h:904:12: error: no viable conversion from returned value of type 'v8::MaybeLocal<v8::Object>' to function return type
      'v8::Local<v8::Object>'
    return node::Buffer::New(v8::Isolate::GetCurrent(), size);
           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/Users/scottj/.node-gyp/6.11.2/include/node/v8.h:218:7: note: candidate constructor (the implicit copy constructor) not viable: no known conversion
      from 'v8::MaybeLocal<v8::Object>' to 'const v8::Local<v8::Object> &' for 1st argument
class Local {
      ^
/Users/scottj/.node-gyp/6.11.2/include/node/v8.h:218:7: note: candidate constructor (the implicit move constructor) not viable: no known conversion
      from 'v8::MaybeLocal<v8::Object>' to 'v8::Local<v8::Object> &&' for 1st argument
/Users/scottj/.node-gyp/6.11.2/include/node/v8.h:222:13: note: candidate template ignored: could not match 'Local' against 'MaybeLocal'
  V8_INLINE Local(Local<S> that)
            ^
In file included from ../src/Canvas.cc:7:
In file included from ../src/Canvas.h:22:
../../nan/nan.h:911:26: error: no member named 'Use' in namespace 'node::Buffer'
    return node::Buffer::Use(v8::Isolate::GetCurrent(), data, size);
           ~~~~~~~~~~~~~~^
../../nan/nan.h:938:32: warning: 'Compile' is deprecated [-Wdeprecated-declarations]
    return v8::ScriptCompiler::Compile(v8::Isolate::GetCurrent(), &source);
                               ^
/Users/scottj/.node-gyp/6.11.2/include/node/v8.h:1352:10: note: 'Compile' has been explicitly marked deprecated here
  static V8_DEPRECATED(
         ^
/Users/scottj/.node-gyp/6.11.2/include/node/v8config.h:336:29: note: expanded from macro 'V8_DEPRECATED'
  declarator __attribute__((deprecated))
                            ^
In file included from ../src/Canvas.cc:7:
In file included from ../src/Canvas.h:22:
../../nan/nan.h:945:32: warning: 'Compile' is deprecated [-Wdeprecated-declarations]
    return v8::ScriptCompiler::Compile(v8::Isolate::GetCurrent(), &source);
                               ^
/Users/scottj/.node-gyp/6.11.2/include/node/v8.h:1352:10: note: 'Compile' has been explicitly marked deprecated here
  static V8_DEPRECATED(
         ^
/Users/scottj/.node-gyp/6.11.2/include/node/v8config.h:336:29: note: expanded from macro 'V8_DEPRECATED'
  declarator __attribute__((deprecated))
                            ^
fatal error: too many errors emitted, stopping now [-ferror-limit=]
15 warnings and 20 errors generated.
make: *** [Release/obj.target/canvas/src/Canvas.o] Error 1
gyp ERR! build error
gyp ERR! stack Error: `make` failed with exit code: 2
gyp ERR! stack     at ChildProcess.onExit (/Users/scottj/.nvm/versions/node/v6.11.2/lib/node_modules/npm/node_modules/node-gyp/lib/build.js:258:23)
gyp ERR! stack     at emitTwo (events.js:106:13)
gyp ERR! stack     at ChildProcess.emit (events.js:191:7)
gyp ERR! stack     at Process.ChildProcess._handle.onexit (internal/child_process.js:215:12)
gyp ERR! System Darwin 16.7.0
gyp ERR! command "/Users/scottj/.nvm/versions/node/v6.11.2/bin/node" "/Users/scottj/.nvm/versions/node/v6.11.2/lib/node_modules/npm/node_modules/node-gyp/bin/node-gyp.js" "rebuild"
gyp ERR! cwd /Users/scottj/Source/loop-renderer/node_modules/canvas
gyp ERR! node -v v6.11.2
gyp ERR! node-gyp -v v3.6.2
gyp ERR! not ok

Command line error

Getting the following error when using tool on command line - imagediff -d image1 image2 output

/usr/local/lib/node_modules/imagediff/node_modules/canvas/lib/bindings.js:9
throw e;
^
Error: Cannot find module '../build/default/canvas'
at Function.Module._resolveFilename (module.js:338:15)
at Function.Module._load (module.js:280:25)
at Module.require (module.js:362:17)
at require (module.js:378:17)
at Object. (/usr/local/lib/node_modules/imagediff/node_modules/canvas/lib/bindings.js:7:20)
at Module._compile (module.js:449:26)
at Object.Module._extensions..js (module.js:467:10)
at Module.load (module.js:356:32)
at Function.Module._load (module.js:312:12)
at Module.require (module.js:362:17)

Open to new maintainers?

This is the closest library I could find for my needs but I was disheartened to see it's so outdated.

I started a fork at @christopher_carman/imagediff (changes so far) and would happily contribute back upstream.

Jasmine Matcher w/ Non-elements

The Jasmine matcher toImageDiffEqual fails incorrectly when one of the test or expected values is not a DOM element (ie is a CanvasRenderingContext2D or ImageData). These cannot be inserted into the DOM.

npm package for browser

I am in the process of moving all dependencies from bower to npm (a good read is http://dontkry.com/posts/code/browserify-and-the-universal-module-definition.html). Now I would like to depend on imagediff through npm for browser-facing code.

The npm package for imagediff however depends on canvas which itself has a dependency (cairo) that needs manual installation. For browser-facing code this dependency is not needed and this manual installation step is a deal breaker.

It would be super helpful if we could provide a npm package without that strictly required dependency. I see two options here:

  1. Publish a second package to npm just for the use in browsers, say imagediff-browser.
  2. Make the dependency on canvas optional (via optionalDependencies, https://npmjs.org/doc/json.html#optionalDependencies).

Any more that I missed?

Personally I would prefer option 2. This would be as simple as changing "dependencies" in package.json to "optionalDependencies". npm will still try to install canvas, but will skip if installation fails and return successfully.

The issue with step 2 is that NodeJS users will yield a working dependency installation while the setup is not complete. One way of mitigating that would be to throw an error indicating the unmet dependency.

What do you think?

Use of imagediff with Jasmine / Karma / RequireJS

I have project divided into modules handled with RequireJS. I would like to use imagediff as Jasmine matcher but currently I cannot load it properly. Loading it with RequireJS / define() results with

TypeError: '[object Object]' is not a constructor (evaluating 'new Canvas()')
  at D:/Tools/d3js-dot/lib/js-imagediff/imagediff.js:39

It is because define() is calls definition with own arguments where third (as Canvas expected) is an object with some metadata.

One and only way to make it running is to replace canvas = Canvas ? with canvas = !window && Canvas ? to skip wrong parameter.

Update node-canvas dependency

Any chance the version of node-canvas being used could be updated? The version referenced in package.json still uses waf instead of gyp so running it on windows is a nightmare.

Unexpected ImageTypeError

I am using jasmine (running from grunt) to test the diff between an image and canvas object and getting an unexpected ImageTypeError: Submitted object was not an image. when running toImageDiffEqual.

To make sure the objects I am passing into toImageDiffEqual are actual Image objects I tried testing them with isImage like so:

expect(imagediff.isImage($img[0])).toBe(true);

which passes.

When I try testing the $img[0] against itself in toImageDiffEqual like so:

expect($img[0]).toImageDiffEqual($img[0]);

I get the ImageTypeError.

Any idea what I could be doing wrong here?

Security - Medium severity - Vulnerable module: [email protected]

Trying to use js-imagediff from jsdeliver which complains about security issue in the package.

Js deliver download page wait some seconds and until the varning message is shown. It leads to the
Snyk report on the issue.

MEDIUM SEVERITY
Denial of Service (DoS)
Vulnerable module: canvas, Introduced through: [email protected]

Detailed paths
Introduced through: [email protected][email protected]

Remediation: Upgrade to [email protected].

Overview
canvas is a Cairo-backed Canvas implementation for Node.js.

Affected versions of this package are vulnerable to Denial of Service (DoS). Processing malicious JPEGs or GIFs files could crash the node process.

Denial of Service (DoS) vulnerability report

Maybe just an old version on Js deliver ?
It says 1.0.8 on the Js deliver page but in the code comments it says 1.0.3

DOM error on first time load

The Jasmine matchers in imagediff are brilliant, but unfortunately I can't get them to work first time with Chrome. That is, if I load a suite with toImageDiffEqual matchters in a new tab, I get the following error:
INDEX_SIZE_ERR: INDEX_SIZE_ERR: DOM Exception 1

Refreshing the browser seems to fix the issue.

Unfortunately that doesn't help me in phantomjs (runs all our specs), which throws the following error:
INDEX_SIZE_ERR: INDEX_SIZE_ERR: DOM Exception 1 in file:///[PATH TO TEMP DIRECTORY]/imagediff.js (line 97)

I can provide a more detailed example if needed.

js-imagediff without canvas module (working with phantomjs)

I would like to use js-imagediff without the node canvas module and rely on browser canvas only.

However, when I call require('imagediff') it always complains that the Canvas module is missing.

After a bit of search I found that the initial bower only imagediff had no need for the canvas module.

I tried to require imagediff from bower, npm and from the file manually, but the problem is always there.

Is it possible to do it ? If so how ? Thanks in advance.

Running with Protractor

Is imagediff compatible with Protractor?
I installed imagediff and am able to run it from the terminal no problem, but when I try to write a Jasmine spec using Protractor it gives an error on the

  beforeEach(function () {
    this.addMatchers(imagediff.jasmine);
  });

part, and says "ReferenceError: imagediff is not defined".
I am trying an almost identical test case as the demo provided and I am also getting an error "Image is not defined" at the

a = new Image(),

line.

Can't get this to work with jasmine (2.1.3) in browser

image loaded Object {class: SymbolWinsComponent, stage: Stage, g: Graphics} img src=​"favicon-16x16.png"
imagediff.js:270 Uncaught #checkType @ imagediff.js:270imagediff.equal @ imagediff.js:374jasmine.toImageDiffEqual @ imagediff.js:333Expectation.wrapCompare @ jasmine.js:1331img.onload @ SymbolWinsComponentSpec.js:26

my test fails always fails see the comment below:

// Validation
function checkType () {
var i;
for (i = 0; i < arguments.length; i++) {
if (!isImageType(arguments[i])) {
throw { //###### < ERROR THROWN #######
name : 'ImageTypeError',
message : 'Submitted object was not an image.'
};
}
}
}

below is my test:

beforeEach(function () {
    this.class = new G.SymbolWinsComponent();
    jasmine.addMatchers(imagediff.jasmine);

    this.stage = new createjs.Stage(imagediff.createCanvas(116, 103));
    var self = this;

    compareImage = function (path, done, expect, pixelTolerance) {
        //var stage = this.stage;
        self.stage.update();

        var img = new Image();
        img.src = path;
        img.onload = function () {
            var pixels = this.width * this.height;
            var tolerance = pixels * (typeof pixelTolerance === 'undefined' ? 0.005 :   pixelTolerance);

            console.log('image loaded', self, this);

            expect(self.stage.canvas).toImageDiffEqual(this, tolerance); //###### < ERROR THROWN #######
            done();
        };
        img.onerror = function(){
            fail(img.src + ' failed to load');
            done();
        };
    };

it("Correct M1 animation frame 000 is shown", function(done) {

    var shape = new createjs.Shape();
    this.g = shape.graphics;
    this.stage.addChild(shape);
    this.g.setStrokeStyle(2);
    this.g.beginStroke(this.sColor);
    this.g.beginFill(this.fColor);
    this.g.moveTo(120, 100).arc(100, 100, 20, 0, Math.PI);

    compareImage("/javascripts/test/assets/m1-sprite__000.png", done, expect, 0.01);

});

Does not work from command line (Ubuntu 14.04)

Both modes do not work for me from command line::

dan@dan:~/Downloads$ imagediff -d image_103.jpg image_104.jpg diff.jpg
[Image image_103.jpg]

/usr/lib/node_modules/imagediff/imagediff.js:121
context.drawImage(image, 0, 0);
^
Error: Image given has not completed loading
at toImageDataFromImage (/usr/lib/node_modules/imagediff/imagediff.js:121:13)
at toImageData (/usr/lib/node_modules/imagediff/imagediff.js:108:35)
at Object.imagediff.toImageData (/usr/lib/node_modules/imagediff/imagediff.js:366:14)
at commandLine (/usr/lib/node_modules/imagediff/bin/imagediff:50:17)
at Object. (/usr/lib/node_modules/imagediff/bin/imagediff:6:1)
at Module._compile (module.js:456:26)
at Object.Module._extensions..js (module.js:474:10)
at Module.load (module.js:356:32)
at Function.Module._load (module.js:312:12)
at Function.Module.runMain (module.js:497:10)

dan@dan:~/Downloads$ imagediff -e image_103.jpg image_104.jpg
[Image image_103.jpg]

/usr/lib/node_modules/imagediff/imagediff.js:121
context.drawImage(image, 0, 0);
^
Error: Image given has not completed loading
at toImageDataFromImage (/usr/lib/node_modules/imagediff/imagediff.js:121:13)
at toImageData (/usr/lib/node_modules/imagediff/imagediff.js:108:35)
at Object.imagediff.toImageData (/usr/lib/node_modules/imagediff/imagediff.js:366:14)
at commandLine (/usr/lib/node_modules/imagediff/bin/imagediff:50:17)
at Object. (/usr/lib/node_modules/imagediff/bin/imagediff:6:1)
at Module._compile (module.js:456:26)
at Object.Module._extensions..js (module.js:474:10)
at Module.load (module.js:356:32)
at Function.Module._load (module.js:312:12)
at Function.Module.runMain (module.js:497:10)

Problem using with webpack

I'm trying to use imagediff with webpack (actually, karma-webpack).
During "compilation", I get

ERROR in ./~/imagediff/imagediff.js
Module not found: Error: Cannot resolve module 'fs' in [...]/node_modules/imagediff
 @ ./~/imagediff/imagediff.js 336:4-17

Then the tests are launched and I see

  Uncaught TypeError: Cannot read property 'imagediff' of undefined
  at [...]/karma/tests/visualfill.js:69949 <- webpack:///~/imagediff/imagediff.js:37:4

Looking a bit at the source (not that I understand much), I see things like

  if (typeof module !== 'undefined') {
    imagediff.imageDataToPNG = imageDataToPNG;
  }

even though I think webpack defines module.

Also

(function (name, definition) {
  var root = this;

I think this is undefined there (in strict mode).

"Submitted object was not an image" when isImage = true?

I am really confused about this. When I have console.log(imagediff.isImage(chartImage)) it returns true, but this expect(image1).toImageDiffEqual(image2) returns an error saying "Submitted object was not an image". I also get an error when doing imagediff.equal(chartImage, image2) and that one says "Image or Canvas expected".

I'm using "imagediff": "^1.0.6", "canvas": "^1.2.7" and node v0.12.2, and I'm using a Mac. Can I get some help?

Release 1.0.9 to avoid installation error

I experienced following error when I tried to install imagediff.

$ npm install imagediff

> [email protected] install /home/phanect/Dropbox/dev/pfglps/node_modules/canvas
> node-gyp rebuild

gyp WARN download NVM_NODEJS_ORG_MIRROR is deprecated and will be removed in node-gyp v4, please use NODEJS_ORG_MIRROR
gyp WARN download NVM_NODEJS_ORG_MIRROR is deprecated and will be removed in node-gyp v4, please use NODEJS_ORG_MIRROR
gyp WARN download NVM_NODEJS_ORG_MIRROR is deprecated and will be removed in node-gyp v4, please use NODEJS_ORG_MIRROR
make: Entering directory '/home/phanect/Dropbox/dev/pfglps/node_modules/canvas/build'
  SOLINK_MODULE(target) Release/obj.target/canvas-postbuild.node
  COPY Release/canvas-postbuild.node
  CXX(target) Release/obj.target/canvas/src/Canvas.o
In file included from ../src/Canvas.h:22:0,
                 from ../src/Canvas.cc:7:
../../nan/nan.h: In function ‘v8::Local<v8::Signature> NanNew(v8::Handle<v8::FunctionTemplate>, int, v8::Handle<v8::FunctionTemplate>*)’:
../../nan/nan.h:342:78: error: no matching function for call to ‘v8::Signature::New(v8::Isolate*, v8::Handle<v8::FunctionTemplate>&, int&, v8::Handle<v8::FunctionTemplate>*&)’
     return v8::Signature::New(v8::Isolate::GetCurrent(), receiver, argc, argv);
                                                                              ^
../../nan/nan.h:342:78: note: candidate is:
In file included from ../src/Canvas.h:11:0,
                 from ../src/Canvas.cc:7:
/home/phanect/.node-gyp/4.5.0/include/node/v8.h:4675:27: note: static v8::Local<v8::Signature> v8::Signature::New(v8::Isolate*, v8::Local<v8::FunctionTemplate>)
   static Local<Signature> New(
                           ^
/home/phanect/.node-gyp/4.5.0/include/node/v8.h:4675:27: note:   candidate expects 2 arguments, 4 provided
In file included from ../src/Canvas.h:22:0,
                 from ../src/Canvas.cc:7:
../../nan/nan.h: At global scope:
../../nan/nan.h:424:3: error: redefinition of ‘v8::Local<T> NanNew(P) [with T = v8::StringObject; P = v8::Local<v8::String>]’
   NanNew<v8::StringObject, v8::Handle<v8::String> >(
   ^
../../nan/nan.h:417:3: note: ‘v8::Local<T> NanNew(P) [with T = v8::StringObject; P = v8::Local<v8::String>]’ previously declared here
   NanNew<v8::StringObject, v8::Local<v8::String> >(
   ^
../../nan/nan.h:442:36: error: redefinition of ‘template<class T> v8::Local<v8::RegExp> NanNew(v8::Local<v8::String>, v8::RegExp::Flags)’
   NAN_INLINE v8::Local<v8::RegExp> NanNew(
                                    ^
../../nan/nan.h:436:36: note: ‘template<class T> v8::Local<v8::RegExp> NanNew(v8::Handle<v8::String>, v8::RegExp::Flags)’ previously declared here
   NAN_INLINE v8::Local<v8::RegExp> NanNew(
                                    ^
../../nan/nan.h:454:36: error: redefinition of ‘template<class T, class P> v8::Local<v8::RegExp> NanNew(v8::Local<v8::String>, v8::RegExp::Flags)’
   NAN_INLINE v8::Local<v8::RegExp> NanNew(
                                    ^
../../nan/nan.h:448:36: note: ‘template<class T, class P> v8::Local<v8::RegExp> NanNew(v8::Handle<v8::String>, v8::RegExp::Flags)’ previously declared here
   NAN_INLINE v8::Local<v8::RegExp> NanNew(
                                    ^
../../nan/nan.h:623:19: error: ‘NanNew’ declared as an ‘inline’ variable
       v8::String::ExternalAsciiStringResource *resource) {
                   ^
../../nan/nan.h:623:19: warning: ‘always_inline’ attribute ignored [-Wattributes]
../../nan/nan.h:623:19: error: ‘v8::Local<v8::String> NanNew’ redeclared as different kind of symbol
../../nan/nan.h:617:36: note: previous declaration ‘v8::Local<v8::String> NanNew(v8::String::ExternalStringResource*)’
   NAN_INLINE v8::Local<v8::String> NanNew(
                                    ^
../../nan/nan.h:623:7: error: ‘ExternalAsciiStringResource’ is not a member of ‘v8::String’
       v8::String::ExternalAsciiStringResource *resource) {
       ^
../../nan/nan.h:623:48: error: ‘resource’ was not declared in this scope
       v8::String::ExternalAsciiStringResource *resource) {
                                                ^
../../nan/nan.h:637:27: error: redefinition of ‘template<class T> v8::Local<T> _NanEscapeScopeHelper(v8::Local<T>)’
   NAN_INLINE v8::Local<T> _NanEscapeScopeHelper(v8::Local<T> val) {
                           ^
../../nan/nan.h:632:27: note: ‘template<class T> v8::Local<T> _NanEscapeScopeHelper(v8::Handle<T>)’ previously declared here
   NAN_INLINE v8::Local<T> _NanEscapeScopeHelper(v8::Handle<T> val) {
                           ^
../../nan/nan.h:889:13: error: ‘node::smalloc’ has not been declared
     , node::smalloc::FreeCallback callback
             ^
../../nan/nan.h:889:35: error: expected ‘,’ or ‘...’ before ‘callback’
     , node::smalloc::FreeCallback callback
                                   ^
../../nan/nan.h: In function ‘v8::Local<v8::Object> NanNewBufferHandle(char*, size_t, int)’:
../../nan/nan.h:893:50: error: ‘callback’ was not declared in this scope
         v8::Isolate::GetCurrent(), data, length, callback, hint);
                                                  ^
../../nan/nan.h:893:60: error: ‘hint’ was not declared in this scope
         v8::Isolate::GetCurrent(), data, length, callback, hint);
                                                            ^
../../nan/nan.h: In function ‘v8::Local<v8::Object> NanNewBufferHandle(const char*, uint32_t)’:
../../nan/nan.h:900:67: error: call of overloaded ‘New(v8::Isolate*, const char*&, uint32_t&)’ is ambiguous
     return node::Buffer::New(v8::Isolate::GetCurrent(), data, size);
                                                                   ^
../../nan/nan.h:900:67: note: candidates are:
In file included from ../../nan/nan.h:179:0,
                 from ../src/Canvas.h:22,
                 from ../src/Canvas.cc:7:
/home/phanect/.node-gyp/4.5.0/include/node/node_buffer.h:34:40: note: v8::MaybeLocal<v8::Object> node::Buffer::New(v8::Isolate*, v8::Local<v8::String>, node::encoding) <near match>
 NODE_EXTERN v8::MaybeLocal<v8::Object> New(v8::Isolate* isolate,
                                        ^
/home/phanect/.node-gyp/4.5.0/include/node/node_buffer.h:34:40: note:   no known conversion for argument 3 from ‘uint32_t {aka unsigned int}’ to ‘node::encoding’
/home/phanect/.node-gyp/4.5.0/include/node/node_buffer.h:46:40: note: v8::MaybeLocal<v8::Object> node::Buffer::New(v8::Isolate*, char*, size_t) <near match>
 NODE_EXTERN v8::MaybeLocal<v8::Object> New(v8::Isolate* isolate,
                                        ^
/home/phanect/.node-gyp/4.5.0/include/node/node_buffer.h:46:40: note:   no known conversion for argument 2 from ‘const char*’ to ‘char*
In file included from ../src/Canvas.h:22:0,
                 from ../src/Canvas.cc:7:
../../nan/nan.h: In function ‘v8::Local<v8::Object> NanNewBufferHandle(uint32_t)’:
../../nan/nan.h:904:61: error: could not convert ‘node::Buffer::New(v8::Isolate::GetCurrent(), ((size_t)size))’ from ‘v8::MaybeLocal<v8::Object>’ to ‘v8::Local<v8::Object>
     return node::Buffer::New(v8::Isolate::GetCurrent(), size);
                                                             ^
../../nan/nan.h: In function ‘v8::Local<v8::Object> NanBufferUse(char*, uint32_t)’:
../../nan/nan.h:911:12: error: ‘Use’ is not a member of ‘node::Buffer’
     return node::Buffer::Use(v8::Isolate::GetCurrent(), data, size);
            ^
../../nan/nan.h: In function ‘bool _NanGetExternalParts(v8::Handle<v8::Value>, const char**, size_t*)’:
../../nan/nan.h:1993:12: error: ‘class v8::String’ has no member named ‘IsExternalAscii’
   if (str->IsExternalAscii()) {
            ^
../../nan/nan.h:1994:23: error: ‘ExternalAsciiStringResource’ in ‘class v8::String’ does not name a type
     const v8::String::ExternalAsciiStringResource* ext;
                       ^
../../nan/nan.h:1995:5: error: ‘ext’ was not declared in this scope
     ext = str->GetExternalAsciiStringResource();
     ^
../../nan/nan.h:1995:16: error: ‘class v8::String’ has no member named ‘GetExternalAsciiStringResource’
     ext = str->GetExternalAsciiStringResource();
                ^
../../nan/nan.h: In function ‘v8::Local<v8::Object> NanNewBufferHandle(const char*, uint32_t)’:
../../nan/nan.h:901:3: warning: control reaches end of non-void function [-Wreturn-type]
   }
   ^
canvas.target.mk:123: recipe for target 'Release/obj.target/canvas/src/Canvas.o' failed
make: *** [Release/obj.target/canvas/src/Canvas.o] Error 1
make: Leaving directory '/home/phanect/Dropbox/dev/pfglps/node_modules/canvas/build'
gyp ERR! build error 
gyp ERR! stack Error: `make` failed with exit code: 2
gyp ERR! stack     at ChildProcess.onExit (/home/phanect/.nvm/versions/node/v4.5.0/lib/node_modules/npm/node_modules/node-gyp/lib/build.js:276:23)
gyp ERR! stack     at emitTwo (events.js:87:13)
gyp ERR! stack     at ChildProcess.emit (events.js:172:7)
gyp ERR! stack     at Process.ChildProcess._handle.onexit (internal/child_process.js:200:12)
gyp ERR! System Linux 3.16.0-4-amd64
gyp ERR! command "/home/phanect/.nvm/versions/node/v4.5.0/bin/node" "/home/phanect/.nvm/versions/node/v4.5.0/lib/node_modules/npm/node_modules/node-gyp/bin/node-gyp.js" "rebuild"
gyp ERR! cwd /home/phanect/Dropbox/dev/pfglps/node_modules/canvas
gyp ERR! node -v v4.5.0
gyp ERR! node-gyp -v v3.4.0
gyp ERR! not ok 
npm WARN install:[email protected] [email protected] install: `node-gyp rebuild`
npm WARN install:[email protected] Exit status 1
[email protected] /home/phanect/Dropbox/dev/pfglps
└── [email protected] 

I tried to remove node_modules directory, and tried to dev version npm install HumbleSoftware/js-imagediff and successfully installed. This problem should be already solved, but not released yet for 2 years.
According to above log, imagediff 1.0.8 (current stable) seems to depend on canvas 1.1.x.
You don't experience above error on canvas 1.2+, which current development version of imagediff depends.

I used Debian Jessie and I have installed dependencies:

  • libcairo2-dev
  • libjpeg-dev
  • libpango1.0-dev
  • libgif-dev
  • build-essential
  • g++

(From canvas' Wiki)

Image Diff, restore original image

image diff on a and b retuns c (example you already included)

my idea was to create b by image diff on a nd c

bildschirmfoto 2013-11-16 um 19 29 53

But the colors are different from b:
1_normal_b

Andy idea how to fix that issue?

Jasmine custom matchers should support CLI reporters

It seems that the support for DOM nodes inside Jasmine's custom matchers message object really depends on the reporter the user is employing: jasmine/jasmine#791

imagediff could probably account for that so that for CLI reporters a string is output instead. Right now the karma reporter for example crashes as indexOf() is not supported for a DOM node.

Support browserify

This issue has already been mentioned in #22, however there still seems to be work to do.

The following three things should be tackled for the original packaging to work together with browserify:

  • Node.js canvas dependency should be optional (#22) ✓
  • Canvas dependency resolution needs to fallback to the browser support in a require-style environment (#28)
  • Packaging with browserify should work without the need to resolve the canvas dependency.

The latter can be solved by the following solutions:

  1. Tell browserify to exclude the canvas dependency. The following is a hacky solution that works for me:

    $ npm install browserify
    $ touch canvasShim.js
    $ ./node_modules/.bin/browserify -e js/imagediff.js -s imagediff -r ./canvasShim.js:canvas --exclude ./canvasShim.js -o imagediff.browserified.js
    

    Or in human language: Package imagediff (-e) as a standalone package (-s) by replacing the canvas dependency with our mock (-r) that you shall not include (--exclude).

  2. Use canvas-browserify to always provide a Node.js package, but one that actually works in the browser.

    1. Either, completely remove the homegrown getCanvas() method, thus delegating this to canvas-browserify. This will however sacrifice the ability of the produced artifact to be usable in the browser out-of-the-box.
    2. Or, keep the getCanvas() implementation, but in the case of the browserify bundle use the implementation provided by canvas-browserify. We will produce code duplication, but then all cases should be covered.
  3. Ask around for other solutions.

I would currently favour 2.ii.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.