How to compare two images using Node.js

49.7k views Asked by At

I am looking for a way to compare two images to see how similar they are. Googling it produces tons of image processing results (cropping, re-sizing, etc.), but nothing that would do approximate comparisons of images. There is one Node.js library, but it is version 0.0.1 and relies on various 3rd party system packages, so not stable or portable.

Something along these lines:

var imgComparator = require('some-awesome-image-comparator-module');
// result would be between 1.0 and 0.0, where 1.0 would mean exact match
var result = imgComparator.compare('/path/to/image/1.png', '/path/to/image/2.png');
4

There are 4 answers

0
moka On BEST ANSWER

There is node-opencv module, you might use it in order to perform heavy operation like image comparison. Good topic on that is here: Simple and fast method to compare images for similarity

3
Linus Unnebäck On

There is also image-diff which looks very promising, it's made by Uber.

var imageDiff = require('image-diff')

imageDiff({
  actualImage: 'checkerboard.png',
  expectedImage: 'white.png'
}, function (err, imagesAreSame) {
  // error will be any errors that occurred
  // imagesAreSame is a boolean whether the images were the same or not
  // diffImage will have an image which highlights differences
})
2
Emeric On

image-diff is deprecated.

From their github:

We no longer have any active maintainers on this project and as a result have halted maintenance.

As a replacement, please see alternative projects like looks-same and pixelmatch:

https://github.com/gemini-testing/looks-same

https://github.com/mapbox/pixelmatch

I personally use pixelmatch:

The smallest, simplest and fastest JavaScript pixel-level image comparison library, originally created to compare screenshots in tests.

Features accurate anti-aliased pixels detection and perceptual color difference metrics.

Inspired by Resemble.js and Blink-diff. Unlike these libraries, pixelmatch is around 150 lines of code, has no dependencies, and works on raw typed arrays of image data, so it's blazing fast and can be used in any environment (Node or browsers).

const fs = require('fs');
const PNG = require('pngjs').PNG;
const pixelmatch = require('pixelmatch');

const img1 = PNG.sync.read(fs.readFileSync('img1.png'));
const img2 = PNG.sync.read(fs.readFileSync('img2.png'));
const {width, height} = img1;
const diff = new PNG({width, height});

const difference = pixelmatch(img1.data, img2.data, diff.data, width, height, {threshold: 0.1});

fs.writeFileSync('diff.png', PNG.sync.write(diff)); // see diff.png for the difference

const compatibility = 100 - dif * 100 / (width * height);
console.log(`${difference} pixels differents`);
console.log(`Compatibility: ${compatibility}%`);

Find a demo here: https://observablehq.com/@mourner/pixelmatch-demo

https://github.com/mapbox/pixelmatch

2
Dan On

I have found this library, which may be useful for you

https://github.com/HumbleSoftware/js-imagediff