image-comparator
Advanced tools
Comparing version 1.2.0 to 1.3.0
@@ -11,3 +11,3 @@ const { | ||
module.exports = { | ||
compare: async (buffer1, buffer2) => { | ||
compare: async (buffer1, buffer2, comparator) => { | ||
const isInterformatComparison = | ||
@@ -22,4 +22,4 @@ buffer1[0] === MIMES.WEBP && buffer1[0] !== buffer2[0]; | ||
...(await Promise.all([compareImpl(buffer1), compareImpl(buffer2)])), | ||
BYTE_COMPARERS[buffer1[0]], | ||
BYTE_COMPARERS[buffer2[0]], | ||
comparator || BYTE_COMPARERS[buffer1[0]], | ||
comparator || BYTE_COMPARERS[buffer2[0]], | ||
buffer1[0] | ||
@@ -26,0 +26,0 @@ ); |
{ | ||
"name": "image-comparator", | ||
"version": "1.2.0", | ||
"version": "1.3.0", | ||
"description": "Compares images by resizing without dependencies", | ||
@@ -5,0 +5,0 @@ "main": "index.js", |
@@ -29,15 +29,94 @@ # image-comparator | ||
const areSame = await comparator.compare(imageBuffer1, imageBuffer2); | ||
const compare = async () => { | ||
const areSame = await comparator.compare(imageBuffer1, imageBuffer2); | ||
if (areSame) { | ||
console.log("Images are the same"); | ||
} else { | ||
console.log("Images are different"); | ||
} | ||
if (areSame) { | ||
console.log("Images are the same"); | ||
} else { | ||
console.log("Images are different"); | ||
} | ||
}; | ||
compare(); | ||
``` | ||
## Supported formats | ||
### With custom threshold | ||
```js | ||
const fs = require("node:fs"); | ||
const comparator = require("image-comparator"); | ||
const imagePath1 = "path/to/same.png"; | ||
const imagePath2 = "path/to/same.jpg"; | ||
const imageBuffer1 = fs.readFileSync(imagePath1); | ||
const imageBuffer2 = fs.readFileSync(imagePath2); | ||
const compare = async () => { | ||
const compareFunction = (byte1, byte2) => false; // Images are always different | ||
const areSame = await comparator.compare( | ||
imageBuffer1, | ||
imageBuffer2, | ||
compareFunction | ||
); | ||
if (areSame) { | ||
throw new Error("Should not happen"); | ||
} else { | ||
console.log("Images are different"); | ||
} | ||
}; | ||
compare(); | ||
``` | ||
```js | ||
const fs = require("node:fs"); | ||
const comparator = require("image-comparator"); | ||
const imagePath1 = "path/to/same.png"; | ||
const imagePath2 = "path/to/same.jpg"; | ||
const imageBuffer1 = fs.readFileSync(imagePath1); | ||
const imageBuffer2 = fs.readFileSync(imagePath2); | ||
const compare = async () => { | ||
const compareFunction = (byte1, byte2) => Math.abs(byte1 - byte2) < 128; // If color difference is small enough | ||
const areSame = await comparator.compare( | ||
imageBuffer1, | ||
imageBuffer2, | ||
compareFunction | ||
); | ||
if (areSame) { | ||
console.log("Images are the same"); | ||
} else { | ||
console.log("Images are different"); | ||
} | ||
}; | ||
compare(); | ||
``` | ||
# API | ||
```js | ||
compare: ( | ||
buffer1: Buffer, | ||
buffer2: Buffer, | ||
compareFunction: (byte1, byte2) => boolean | ||
) => bool; | ||
``` | ||
Compares two images. | ||
Throws if WEBP image is compared with imag of another extension. | ||
## Supported extensions | ||
- png | ||
- jpg | ||
- webp | ||
@@ -52,2 +131,3 @@ ## Detection algorithm | ||
May produce false positives for comparison of images of different format origins due to inconsistent resulting bitmap size | ||
- May produce false positives for comparison of images of different format origins due to inconsistent resulting bitmap size (use `compareFunction` to avoid this) | ||
- Can work with interformat images, but WEBP is not supported for this at the moment |
@@ -34,2 +34,26 @@ const assert = require("node:assert"); | ||
}); | ||
it("should perceive different images as same with low threshold", async () => { | ||
const expected = true; | ||
const comparator = (byte1, byte2) => Math.abs(byte1 - byte2) < 256; | ||
const commonPathSegments = [...commonPngImagesPath, "different"]; | ||
const image1 = readFileSync(join(...commonPathSegments, "image1.png")); | ||
const image2 = readFileSync(join(...commonPathSegments, "image2.png")); | ||
const actual = await compare(image1, image2, comparator); | ||
assert.strictEqual(actual, expected); | ||
}); | ||
it("should perceive same images as different with high threshold", async () => { | ||
const expected = false; | ||
const comparator = (byte1, byte2) => Math.abs(byte1 - byte2) > 255; | ||
const commonPathSegments = [...commonPngImagesPath, "same"]; | ||
const image1 = readFileSync(join(...commonPathSegments, "image1.png")); | ||
const image2 = readFileSync(join(...commonPathSegments, "image2.png")); | ||
const actual = await compare(image1, image2, comparator); | ||
assert.strictEqual(actual, expected); | ||
}); | ||
}); | ||
@@ -61,10 +85,34 @@ | ||
}); | ||
it("should perceive different images as same with low threshold", async () => { | ||
const expected = true; | ||
const comparator = (byte1, byte2) => Math.abs(byte1 - byte2) < 256; | ||
const commonPathSegments = [...commonJpgImagesPath, "different"]; | ||
const image1 = readFileSync(join(...commonPathSegments, "image1.jpg")); | ||
const image2 = readFileSync(join(...commonPathSegments, "image2.jpg")); | ||
const actual = await compare(image1, image2, comparator); | ||
assert.strictEqual(actual, expected); | ||
}); | ||
it("should perceive same images as different with high threshold", async () => { | ||
const expected = false; | ||
const comparator = (byte1, byte2) => Math.abs(byte1 - byte2) > 255; | ||
const commonPathSegments = [...commonJpgImagesPath, "same"]; | ||
const image1 = readFileSync(join(...commonPathSegments, "image1.jpg")); | ||
const image2 = readFileSync(join(...commonPathSegments, "image2.jpg")); | ||
const actual = await compare(image1, image2, comparator); | ||
assert.strictEqual(actual, expected); | ||
}); | ||
}); | ||
describe("webp", () => { | ||
const commonJpgImagesPath = [...commonImagesPath, "webp"]; | ||
const commonWebpImagesPath = [...commonImagesPath, "webp"]; | ||
it("should return false for different webp images", async () => { | ||
const expected = false; | ||
const commonPathSegments = [...commonJpgImagesPath, "different"]; | ||
const commonPathSegments = [...commonWebpImagesPath, "different"]; | ||
const image1 = readFileSync(join(...commonPathSegments, "image1.webp")); | ||
@@ -80,3 +128,3 @@ const image2 = readFileSync(join(...commonPathSegments, "image2.webp")); | ||
const expected = true; | ||
const commonPathSegments = [...commonJpgImagesPath, "same"]; | ||
const commonPathSegments = [...commonWebpImagesPath, "same"]; | ||
const image1 = readFileSync(join(...commonPathSegments, "image1.webp")); | ||
@@ -89,2 +137,26 @@ const image2 = readFileSync(join(...commonPathSegments, "image2.webp")); | ||
}); | ||
it("should perceive different images as same with low threshold", async () => { | ||
const expected = true; | ||
const comparator = (byte1, byte2) => Math.abs(byte1 - byte2) < 256; | ||
const commonPathSegments = [...commonWebpImagesPath, "different"]; | ||
const image1 = readFileSync(join(...commonPathSegments, "image1.webp")); | ||
const image2 = readFileSync(join(...commonPathSegments, "image2.webp")); | ||
const actual = await compare(image1, image2, comparator); | ||
assert.strictEqual(actual, expected); | ||
}); | ||
it("should perceive same images as different with high threshold", async () => { | ||
const expected = false; | ||
const comparator = (byte1, byte2) => Math.abs(byte1 - byte2) > 255; | ||
const commonPathSegments = [...commonWebpImagesPath, "same"]; | ||
const image1 = readFileSync(join(...commonPathSegments, "image1.webp")); | ||
const image2 = readFileSync(join(...commonPathSegments, "image2.webp")); | ||
const actual = await compare(image1, image2, comparator); | ||
assert.strictEqual(actual, expected); | ||
}); | ||
}); | ||
@@ -137,2 +209,14 @@ | ||
}); | ||
it("should perceive same interformat images as different with high threshold", async () => { | ||
const expected = false; | ||
const comparator = (byte1, byte2) => Math.abs(byte1 - byte2) > 255; | ||
const commonPathSegments = [...commonImagesPath, "mixins"]; | ||
const image1 = readFileSync(join(...commonPathSegments, "image.jpg")); | ||
const image2 = readFileSync(join(...commonPathSegments, "image.png")); | ||
const actual = await compare(image1, image2, comparator); | ||
assert.strictEqual(actual, expected); | ||
}); | ||
}); |
183033
3089
132