SSIM.JS Image Similarity
ssim.js is a JavaScript library that provides an implementation of the Structural Similarity Index (SSIM) algorithm, which measures the perceived similarity between two images. Unlike traditional metrics like PSNR or MSE, SSIM correlates more closely with human visual perception, yielding a score between 0 and 1, where 1 indicates perfect similarity. The library also supports MSSIM (Multi-scale SSIM) and can generate SSIM maps. The current stable version is 3.5.0, with releases occurring infrequently, often several months apart, as seen from the recent release history. Its key differentiator is providing a readily available, pure JavaScript SSIM implementation suitable for both Node.js and browser environments, often used in image processing, quality assessment, and content-based image retrieval applications.
Common errors
-
TypeError: Cannot read properties of undefined (reading 'width')
cause The input images passed to `ssim()` are not valid `ImageData` objects or compatible structures, likely missing `width` or `height` properties, or being `null`/`undefined`.fixEnsure `ssim()` receives correctly formatted image data. In Node.js, use a library like `canvas` to load and process image files into `ImageData` objects. In browsers, use `context.getImageData()`. -
Error: Cannot find module 'ssim.js'
cause The `ssim.js` package has not been installed or the import path is incorrect.fixRun `npm install ssim.js` or `yarn add ssim.js`. Verify the import statement `import ssim from 'ssim.js';` for ESM or `const ssim = require('ssim.js');` for CommonJS.
Warnings
- gotcha ssim.js expects raw image pixel data, typically as an `ImageData` object (in browsers) or a compatible buffer structure (in Node.js). Directly passing file paths or `Buffer` objects from file reads will not work without pre-processing the image into a pixel array format.
- breaking Version 3.0.0 introduced Bezkrovny's SSIM algorithm as a feature. While not explicitly marked as a breaking change in the release notes, new algorithm implementations can sometimes subtly alter default behavior or results compared to previous versions, potentially affecting applications sensitive to exact SSIM scores.
- gotcha The performance of SSIM calculation can be significant for large images, especially in JavaScript environments. The `performance` property in the result object indicates the computation time.
Install
-
npm install ssim.js -
yarn add ssim.js -
pnpm add ssim.js
Imports
- ssim
import { ssim } from 'ssim.js';import ssim from 'ssim.js';
- ssim
const { ssim } = require('ssim.js');const ssim = require('ssim.js'); - SSIMResult
import type { SSIMResult } from 'ssim.js';
Quickstart
import { createCanvas, loadImage } from 'canvas';
import ssim from 'ssim.js';
import { readFileSync } from 'fs';
// Load images (replace with actual image paths or buffers)
// In a browser, loadImage would be from the DOM, e.g., an <img> element.
// For Node.js, we simulate with `canvas` library or direct buffer.
async function compareImages() {
try {
// For this example, we create dummy images or load from disk.
// In a real scenario, these would be actual image buffers/data.
const imgBuffer1 = readFileSync('./image1.png'); // Ensure you have image1.png and image2.png
const imgBuffer2 = readFileSync('./image2.png');
const image1 = await loadImage(imgBuffer1);
const image2 = await loadImage(imgBuffer2);
// ssim.js expects image data in a specific format (e.g., ImageData or a compatible buffer).
// Here we convert the loaded image to a format ssim.js can process.
// The `canvas` library helps create a compatible buffer.
const canvas1 = createCanvas(image1.width, image1.height);
const ctx1 = canvas1.getContext('2d');
ctx1.drawImage(image1, 0, 0, image1.width, image1.height);
const imageData1 = ctx1.getImageData(0, 0, image1.width, image1.height);
const canvas2 = createCanvas(image2.width, image2.height);
const ctx2 = canvas2.getContext('2d');
ctx2.drawImage(image2, 0, 0, image2.width, image2.height);
const imageData2 = ctx2.getImageData(0, 0, image2.width, image2.height);
const { mssim, performance } = ssim(imageData1, imageData2);
console.log(`Structural Similarity (MSSIM): ${mssim}`);
console.log(`Calculation Performance: ${performance}ms`);
if (mssim > 0.95) {
console.log('The images are very similar.');
} else {
console.log('The images show significant differences.');
}
} catch (error) {
console.error('Error comparing images:', error);
console.log('Please ensure you have two image files (e.g., image1.png, image2.png) in the same directory and have installed `canvas` (`npm install canvas`).');
}
}
compareImages();