img-hash-js-core

1.0.7 • Public • Published

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.

Package Sidebar

Install

npm i img-hash-js-core

Weekly Downloads

4

Version

1.0.7

License

MIT

Unpacked Size

25.8 kB

Total Files

11

Last publish

Collaborators

  • kobaj