prcp
A tiny and fast perceptual image hashing algorithm for JavaScript.
- Small. 837 bytes (minified and gzipped). No dependencies.
- Portable. Supports modern browsers and Node.js.
- Fast.
This algorithm is based on the paper Block Mean Value Based Image Perceptual Hashing.
Usage
NodeJS
- Install using npm
npm install prcp
- Create a hash
const prcp = require('prcp')
const hash = prcp(image) // C3257FEC3610E8F1
Browser
- Import using unpkg
<script src="https://unpkg.com/prcp/dist/index.browser.js"></script>
- Create a hash
<script>
const hash = prcp(image) // 3610E8F1C3257FEC
</script>
API
prcp(image, precision)
Creates a perceptual hash based on the given image.
parameter | type | required | default | description |
---|---|---|---|---|
image |
ImageData |
✓ | Image to hash | |
precision |
Number |
8 | Hash size (N^2 bits) |
Hashes can be compared using the Levenshtein or Hamming distance.
Similar images will not always have a distance equal to 0, which means that you will have to decide at what distance you will evaluate images as equal.
Use cases
A perceptual hashing algorithm could be used to:
- Avoid storing the same image multiple times
- Identify plagiarism
Database lookup
If you need to search a database, I recommend the following approach:
- Create a table with four columns: each column will contain an 16 bits slice of the 64 bits hashes. The number of columns, and their size is up to you.
CREATE TABLE images (
H CHAR(16), -- Full hash
H0 CHAR(4), -- Hash parts
H1 CHAR(4),
H2 CHAR(4),
H3 CHAR(4)
);
- Split your query hash in four parts.
const parts = ['3610', 'E8F1', 'C325', '7FEC']
- Query this table. In this case, it gives you every hash that are within 3 bits (4 - 1) of the query hash.
SELECT H FROM images WHERE H0 = parts[0] OR H1 = parts[1] OR H2 = parts[2] OR H3 = parts[3]
- Compute the exact Hamming distance for each returned hash with your query hash.
const query = '3610E8F1C3257FEC' // Query hash
const hashes = ['36107FEC3610E8F1', '...', '...'] // Database hashes
for (const hash of hashes) {
const distance = hamming(query, hash)
// ...
}
The preceding code is for demonstration purposes only and should be tweaked to fit your use case.
Example
Original
Watermark
Original hash: ffff23c1c0e0e060
Watermark hash: ffff23c1c0e0e060
Hamming distance: 0
Different
Original hash: ffff23c1c0e0e060
Different hash: 3f0020783d3f1f1f
Hamming distance: 14