Image SSIM
Image SSIM is a TypeScript/JavaScript library for calculating the Structural Similarity (SSIM) index between two images, suitable for both browser and server environments. This metric aims to quantify perceived image quality and similarity more effectively than traditional methods like PSNR or MSE, by focusing on structural information. Currently at version 0.2.0, this package is relatively stable for its core functionality, though its low version number suggests it may not receive frequent major feature updates or breaking changes typical of rapidly evolving libraries. Its key differentiator is providing a straightforward, cross-platform implementation of the SSIM algorithm, based on established references in the field. It is designed for developers needing a perceptual image comparison tool without heavy external dependencies. While the `npm` package `img-ssim` offers similar functionality, it uses image paths/URLs and callbacks, whereas `image-ssim` expects raw `ImageData`-like objects and returns a Promise or direct value, making `image-ssim` more suitable for in-memory image processing workflows.
Common errors
-
Error: Images must have identical dimensions for SSIM calculation.
cause Attempting to calculate SSIM between two images that do not have the same width and height. The SSIM algorithm requires pixel-by-pixel correspondence.fixEnsure both input `ImageData` objects have identical `width` and `height` properties before calling `ssim`. Resize one or both images if necessary, although resizing can introduce its own artifacts that affect SSIM. -
TypeError: Cannot read properties of undefined (reading 'data') or other properties of ImageData.
cause The `ssim` function was called with an argument that is not an `ImageData`-like object, meaning it lacks `data`, `width`, or `height` properties, or `data` is not a `Uint8ClampedArray` (or `Uint8Array`).fixVerify that both arguments passed to `ssim` are valid `ImageData` objects or objects structurally identical to `ImageData`, specifically having `data: Uint8ClampedArray`, `width: number`, and `height: number` properties.
Warnings
- gotcha The package is currently at version 0.2.0. While functional, pre-1.0.0 versions may introduce breaking API changes in minor releases without strict adherence to semantic versioning, although this package has been stable for a long time.
- gotcha The `ssim` function expects image data in a specific `ImageData`-like format (an object with `data: Uint8ClampedArray`, `width: number`, `height: number`). Providing malformed or incorrect data structures will lead to errors or inaccurate results.
- gotcha SSIM is primarily defined for grayscale images. When comparing color images, this implementation (and many others) implicitly convert to grayscale or process channels independently. This can lead to SSIM values that may not perfectly reflect human perception of color differences, and some SSIM variants are not rotationally symmetric.
- gotcha The SSIM algorithm can be computationally intensive, especially for large images or if performed frequently. Performance can vary significantly between environments (browser vs. Node.js) and hardware.
- gotcha Many SSIM implementations exist, and their results can vary due to subtle differences in parameters, color space handling, and internal calculations. Comparing SSIM values from different libraries directly might not yield consistent results.
Install
-
npm install image-ssim -
yarn add image-ssim -
pnpm add image-ssim
Imports
- ssim
import ssim from 'image-ssim';
import { ssim } from 'image-ssim'; - ssim
const ssim = require('image-ssim');const { ssim } = require('image-ssim');
Quickstart
import { ssim } from 'image-ssim';
// Helper to create a mock ImageData object for demonstration
const createMockImageData = (width: number, height: number, fillValue: number): ImageData => {
const data = new Uint8ClampedArray(width * height * 4);
for (let i = 0; i < data.length; i += 4) {
data[i] = fillValue; // Red
data[i + 1] = fillValue; // Green
data[i + 2] = fillValue; // Blue
data[i + 3] = 255; // Alpha
}
return { data, width, height };
};
const width = 100;
const height = 100;
// Create two identical images
const imageA = createMockImageData(width, height, 128);
const imageB = createMockImageData(width, height, 128);
// Create a slightly different image
const imageC = createMockImageData(width, height, 138);
// Calculate SSIM between identical images (should be close to 1)
const ssimValueAB = ssim(imageA, imageB);
console.log(`SSIM (Image A vs B - identical): ${ssimValueAB}`);
// Calculate SSIM between different images
const ssimValueAC = ssim(imageA, imageC);
console.log(`SSIM (Image A vs C - different): ${ssimValueAC}`);
// Example with different dimensions (will throw an error if not handled)
try {
const imageD = createMockImageData(50, 50, 128);
ssim(imageA, imageD);
} catch (e: any) {
console.error(`Error with different dimensions: ${e.message}`);
}