img-hash-js-core
v1.0.7
Published
Algorithms for generating image hashes.
Downloads
23
Maintainers
Readme
img-hash-js-core
A js implementation of https://docs.rs/img_hash/ which itself is based on the work of http://www.hackerfactor.com/.
NOTE: If you want a more friendly version of this library then check out https://www.npmjs.com/package/friendly-img-hash-js.
Installation via NPM
npm install img-hash-js-core
Get started quickly
Browser example:
import { hash } from 'img-hash-js-core';
// First get the raw RGBA bytes from the image itself
const canvas = document.createElement('canvas');
const context = canvas.getContext('2d');
const img = document.querySelector('img');
canvas.height = img.naturalHeight;
canvas.width = img.naturalWidth;
context.drawImage(img, 0, 0, img.naturalWidth, img.naturalHeight);
const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
// Trim off the alpha bit
const rgbBytes = imageData.data.filter((_, i) => (i + 1) % 4);
// Construct a hash!
const result = hash(rgbBytes, imageData.width, imageData.height);
Nodejs Example:
import { hash } from 'img-hash-js-core';
// Include an image parsing library
import { PNG } from 'pngjs';
// First get the raw RGBA bytes from the image itself
const fileData = fs.readFileSync('./some/file/on/disk.png');
const png = PNG.sync.read(fileData);
// Trim off the alpha bit
const rgbBytes = png.data.filter((_, i) => (i + 1) % 4);
// Construct a hash!
const result = hash(rgbBytes, png.width, png.height);
Detailed examples and options
You can see all options, including defaults, inside the file index.js. Options can be mixed and matched as much as you like!
Different output types.
import { hash, Convert } from 'img-hash-js-core';
const imageBytes = // get your image bytes following the examples above.
// You can specify the output format as one of the following
// BigInt -> an integer number like 7930450656421763612n
// Base64 -> a base64 string like KNCo2Uw3LtY=
// HexString -> a hex string like 6e0e9edaccc85a1c
// BitArray -> an array of bits like [0, 0, 1, 1, 0, 1, ...]
// Example of how to specify that option
console.log(
hash(imageBytes, width, height, {
output: Convert.options.BigInt
})
);
Different hash algorithms.
import { hash, Hash } from 'img-hash-js-core';
const imageBytes = // get your image bytes following the examples above.
// All of these come from
// https://github.com/abonander/img_hash/blob/dbfb37f9251fea8f7efeabbb2267ddb1fcd21ca6/src/alg/mod.rs#L20
// You can specify the output format as one of the following
// Mean -> Simple algorithm, not very resiliant
// Gradient -> Very effective and efficient algorithm, recommended!
// VerticalGradient -> Same as gradient, but better for tall images
// DoubleGradient -> Computationally expensive, but may improve results
// Example of how to specify that option
console.log(
hash(imageBytes, width, height, {
algorithm: Hash.options.Gradient
})
);
Enable Discrete Cosine Transform (DCT)
import { hash, DCT } from 'img-hash-js-core';
const imageBytes = // get your image bytes following the examples above.
// You can specify the output format as one of the following
// None -> do not enable DCT
// Type2 -> enable DCT, more computation and slightly more robust results
// Example of how to specify that option
console.log(
hash(imageBytes, width, height, {
dct: {
algorithm: Dct.options.Type2
}
})
);
If you want to write your own algorithm, you can for any option. Here is an example of writing a custom hash function (MEDIAN) and a custom output function (BinaryString).
import { hash } from 'img-hash-js-core';
console.log(
hash(imageBytes, width, height, {
// Dimension is required because of custom algorithm
dimension: (width, height) => ({ width, height }),
algorithm: (bytes) => {
const half = Math.floor(bytes.length / 2);
const median = [...bytes].sort().at(half);
return bytes.map((b) => b >= median).map((b) => (b ? 1 : 0));
},
output: (hashBits) => hashBits.join(''),
})
); // Outputs "001010011001..."
Comparing Hashes
If you want to then compare two hashes, use something like Hamming distance or Levenshtein distance
import { hash, Convert } from 'img-hash-js-core';
import leven from 'leven';
const config = { output: Convert.options.BigInt };
const result1 = hash(image1, width, height, config);
const result2 = hash(image2, width, height, config);
if (leven(result1.toString(), result2.toString()) <= 12) {
console.log ('Images are very similar!');
}
Alternatives
The following may fit your usecases better.