friendly-img-hash-js
v1.1.2
Published
User friendly algorithms for generating image hashes.
Downloads
22
Maintainers
Readme
friendly-img-hash-js
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 no dependency, bare bones, and synchronous version of this library then check out https://www.npmjs.com/package/img-hash-js-core.
Installation via NPM
npm install friendly-img-hash-js
Get started quickly
Browser example:
import { hash } from 'friendly-img-hash-js';
// Image formats support depends on your browser
// https://en.wikipedia.org/wiki/Comparison_of_web_browsers#Image_format_support
// Construct a hash!
const result = await hash('https://my-sweet-image-url.png');
Nodejs Example:
import { hash } from 'friendly-img-hash-js';
// Image formats supported are jpeg, png, webp, bitmap, tiff, and avif
// Construct a hash!
const result = await hash('./some/file/on/disk.png');
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 'friendly-img-hash-js';
// 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(
await hash(image {
output: Convert.options.BigInt
})
);
Different hash algorithms.
import { hash, Hash } from 'friendly-img-hash-js';
// 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(
await hash(image, {
algorithm: Hash.options.Gradient
})
);
Enable Discrete Cosine Transform (DCT)
import { hash, Dct } from 'friendly-img-hash-js';
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(
await hash(image, {
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 'friendly-img-hash-js';
console.log(
await hash(image, {
// 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 'friendly-img-hash-js';
import leven from 'leven';
const config = { output: Convert.options.BigInt };
const result1 = await hash(image1, config);
const result2 = await hash(image2, config);
if (leven(result1.toString(), result2.toString()) <= 12) {
console.log ('Images are very similar!');
}
Alternatives
The following may fit your usecases better.