Spaces:
Sleeping
Sleeping
File size: 3,841 Bytes
3530df7 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 | import { JimpClass } from "@jimp/types";
import anyBase from "any-base";
import ImagePHash from "./phash.js";
// an array storing the maximum string length of hashes at various bases
// 0 and 1 do not exist as possible hash lengths
// prettier-ignore
const alphabet =
"0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ$_";
// an array storing the maximum string length of hashes at various bases
// 0 and 1 do not exist as possible hash lengths
const maxHashLength = [NaN, NaN];
for (let i = 2; i < 65; i++) {
const maxHash = anyBase(
anyBase.BIN,
alphabet.slice(0, i),
)(new Array(64 + 1).join("1"));
maxHashLength.push(maxHash.length);
}
export const methods = {
/**
* Calculates the perceptual hash
* @returns the perceptual hash
* @example
* ```ts
* import { Jimp } from "jimp";
*
* const image = await Jimp.read("test/image.png");
*
* image.hash();
* ```
*/
pHash<I extends JimpClass>(image: I) {
const pHash = new ImagePHash();
return pHash.getHash(image);
},
/**
* Generates a perceptual hash of the image <https://en.wikipedia.org/wiki/Perceptual_hashing>. And pads the string. Can configure base.
* @param base A number between 2 and 64 representing the base for the hash (e.g. 2 is binary, 10 is decimal, 16 is hex, 64 is base 64). Defaults to 64.
* @example
* ```ts
* import { Jimp } from "jimp";
*
* const image = await Jimp.read("test/image.png");
*
* image.hash(2); // binary
* image.hash(64); // base 64
* ```
*/
hash<I extends JimpClass>(image: I, base = 64) {
if (base < 2 || base > 64) {
throw new Error("base must be a number between 2 and 64");
}
const subAlphabet = alphabet.slice(0, base);
const pHash = this.pHash(image);
const maxLength = maxHashLength[base]!;
return anyBase(anyBase.BIN, subAlphabet)(pHash).padStart(maxLength, "0");
},
/**
* Calculates the hamming distance of the current image and a hash based on their perceptual hash
* @param compareHash hash to compare to
* @returns a number ranging from 0 to 1, 0 means they are believed to be identical
* @example
* ```ts
* import { Jimp } from "jimp";
*
* const image = await Jimp.read("test/image.png");
*
* image.distanceFromHash(image.pHash());
* ```
*/
distanceFromHash<I extends JimpClass>(image: I, compareHash: string) {
const pHash = new ImagePHash();
const currentHash = pHash.getHash(image);
return pHash.distance(currentHash, compareHash);
},
};
/**
* Calculates the hamming distance of two images based on their perceptual hash
* @param img1 A Jimp image to compare
* @param img2 A Jimp image to compare
* @returns A number ranging from 0 to 1, 0 means they are believed to be identical
* @example
* ```ts
* import { Jimp, distance } from "jimp";
*
* const image1 = await Jimp.read("test/image.png");
* const image2 = await Jimp.read("test/image.png");
*
* distance(image1, image2); // 0.5
* ```
*/
export function distance<I extends JimpClass>(img1: I, img2: I) {
const phash = new ImagePHash();
const hash1 = phash.getHash(img1);
const hash2 = phash.getHash(img2);
return phash.distance(hash1, hash2);
}
/**
* Calculates the hamming distance of two images based on their perceptual hash
* @param hash1 A pHash
* @param hash2 A pHash
* @returns A number ranging from 0 to 1, 0 means they are believed to be identical
* @example
* ```ts
* import { Jimp, compareHashes } from "jimp";
*
* const image1 = await Jimp.read("test/image.png");
* const image2 = await Jimp.read("test/image.png");
*
* compareHashes(image1.pHash(), image2.pHash()); // 0.5
* ```
*/
export function compareHashes(hash1: string, hash2: string) {
const phash = new ImagePHash();
return phash.distance(hash1, hash2);
}
|