Initial commit
This commit is contained in:
commit
e49726988c
5445 files changed
+1089914
No files matched your search
+77
@@ -0,0 +1,77 @@
|
||||
import { JimpClass } from "@jimp/types";
|
||||
export declare 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): string;
|
||||
/**
|
||||
* 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?: number): string;
|
||||
/**
|
||||
* 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): number;
|
||||
};
|
||||
/**
|
||||
* 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 declare function distance<I extends JimpClass>(img1: I, img2: I): number;
|
||||
/**
|
||||
* 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 declare function compareHashes(hash1: string, hash2: string): number;
|
||||
//# sourceMappingURL=index.d.ts.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAuBxC,eAAO,MAAM,OAAO;IAClB;;;;;;;;;;;OAWG;UACG,CAAC,SAAS,SAAS,SAAS,CAAC;IAKnC;;;;;;;;;;;;OAYG;SACE,CAAC,SAAS,SAAS,SAAS,CAAC;IAYlC;;;;;;;;;;;;OAYG;qBACc,CAAC,SAAS,SAAS,SAAS,CAAC,eAAe,MAAM;CAMpE,CAAC;AAEF;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,QAAQ,CAAC,CAAC,SAAS,SAAS,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,UAM7D;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,UAGzD"}
|
||||
+112
@@ -0,0 +1,112 @@
|
||||
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(image) {
|
||||
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(image, 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(image, compareHash) {
|
||||
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(img1, img2) {
|
||||
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, hash2) {
|
||||
const phash = new ImagePHash();
|
||||
return phash.distance(hash1, hash2);
|
||||
}
|
||||
//# sourceMappingURL=index.js.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AACA,OAAO,OAAO,MAAM,UAAU,CAAC;AAE/B,OAAO,UAAU,MAAM,YAAY,CAAC;AAEpC,wEAAwE;AACxE,gDAAgD;AAChD,kBAAkB;AAClB,MAAM,QAAQ,GACZ,kEAAkE,CAAC;AAErE,wEAAwE;AACxE,gDAAgD;AAChD,MAAM,aAAa,GAAG,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;AAEjC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC;IAC5B,MAAM,OAAO,GAAG,OAAO,CACrB,OAAO,CAAC,GAAG,EACX,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CACrB,CAAC,IAAI,KAAK,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;IAC/B,aAAa,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;AACrC,CAAC;AAED,MAAM,CAAC,MAAM,OAAO,GAAG;IACrB;;;;;;;;;;;OAWG;IACH,KAAK,CAAsB,KAAQ;QACjC,MAAM,KAAK,GAAG,IAAI,UAAU,EAAE,CAAC;QAC/B,OAAO,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;IAC9B,CAAC;IAED;;;;;;;;;;;;OAYG;IACH,IAAI,CAAsB,KAAQ,EAAE,IAAI,GAAG,EAAE;QAC3C,IAAI,IAAI,GAAG,CAAC,IAAI,IAAI,GAAG,EAAE,EAAE,CAAC;YAC1B,MAAM,IAAI,KAAK,CAAC,wCAAwC,CAAC,CAAC;QAC5D,CAAC;QAED,MAAM,WAAW,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;QAC5C,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QAChC,MAAM,SAAS,GAAG,aAAa,CAAC,IAAI,CAAE,CAAC;QAEvC,OAAO,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC;IAC3E,CAAC;IAED;;;;;;;;;;;;OAYG;IACH,gBAAgB,CAAsB,KAAQ,EAAE,WAAmB;QACjE,MAAM,KAAK,GAAG,IAAI,UAAU,EAAE,CAAC;QAC/B,MAAM,WAAW,GAAG,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;QAEzC,OAAO,KAAK,CAAC,QAAQ,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC;IAClD,CAAC;CACF,CAAC;AAEF;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,QAAQ,CAAsB,IAAO,EAAE,IAAO;IAC5D,MAAM,KAAK,GAAG,IAAI,UAAU,EAAE,CAAC;IAC/B,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IAClC,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IAElC,OAAO,KAAK,CAAC,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;AACtC,CAAC;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,aAAa,CAAC,KAAa,EAAE,KAAa;IACxD,MAAM,KAAK,GAAG,IAAI,UAAU,EAAE,CAAC;IAC/B,OAAO,KAAK,CAAC,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;AACtC,CAAC"}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"type": "module"
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
import { JimpClass } from "@jimp/types";
|
||||
declare class ImagePHash {
|
||||
size: number;
|
||||
smallerSize: number;
|
||||
constructor(size?: number, smallerSize?: number);
|
||||
distance(s1: string, s2: string): number;
|
||||
/**
|
||||
* Returns a 'binary string' (like. 001010111011100010) which is easy to do a hamming distance on.
|
||||
*/
|
||||
getHash(img: JimpClass): string;
|
||||
}
|
||||
export default ImagePHash;
|
||||
//# sourceMappingURL=phash.d.ts.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"phash.d.ts","sourceRoot":"","sources":["../../src/phash.ts"],"names":[],"mappings":"AAwBA,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAWxC,cAAM,UAAU;IACd,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;gBAER,IAAI,CAAC,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM;IAM/C,QAAQ,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM;IAY/B;;OAEG;IACH,OAAO,CAAC,GAAG,EAAE,SAAS;CAyEvB;AAuDD,eAAe,UAAU,CAAC"}
|
||||
+159
@@ -0,0 +1,159 @@
|
||||
/*
|
||||
Copyright (c) 2011 Elliot Shepherd
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
import { methods as color } from "@jimp/plugin-color";
|
||||
import { methods } from "@jimp/plugin-resize";
|
||||
import { clone } from "@jimp/utils";
|
||||
// https://code.google.com/p/ironchef-team21/source/browse/ironchef_team21/src/ImagePHash.java
|
||||
/*
|
||||
* pHash-like image hash.
|
||||
* Author: Elliot Shepherd (elliot@jarofworms.com
|
||||
* Based On: http://www.hackerfactor.com/blog/index.php?/archives/432-Looks-Like-It.html
|
||||
*/
|
||||
class ImagePHash {
|
||||
size;
|
||||
smallerSize;
|
||||
constructor(size, smallerSize) {
|
||||
this.size = size || 32;
|
||||
this.smallerSize = smallerSize || 8;
|
||||
initCoefficients(this.size);
|
||||
}
|
||||
distance(s1, s2) {
|
||||
let counter = 0;
|
||||
for (let k = 0; k < s1.length; k++) {
|
||||
if (s1[k] !== s2[k]) {
|
||||
counter++;
|
||||
}
|
||||
}
|
||||
return counter / s1.length;
|
||||
}
|
||||
/**
|
||||
* Returns a 'binary string' (like. 001010111011100010) which is easy to do a hamming distance on.
|
||||
*/
|
||||
getHash(img) {
|
||||
/* 1. Reduce size.
|
||||
* Like Average Hash, pHash starts with a small image.
|
||||
* However, the image is larger than 8x8; 32x32 is a good size.
|
||||
* This is really done to simplify the DCT computation and not
|
||||
* because it is needed to reduce the high frequencies.
|
||||
*/
|
||||
img = methods.resize(clone(img), { w: this.size, h: this.size });
|
||||
/* 2. Reduce color.
|
||||
* The image is reduced to a grayscale just to further simplify
|
||||
* the number of computations.
|
||||
*/
|
||||
img = color.greyscale(img);
|
||||
const vals = [];
|
||||
for (let x = 0; x < img.bitmap.width; x++) {
|
||||
const row = [];
|
||||
for (let y = 0; y < img.bitmap.height; y++) {
|
||||
row[y] = intToRGBA(img.getPixelColor(x, y)).b;
|
||||
}
|
||||
vals[x] = row;
|
||||
}
|
||||
/* 3. Compute the DCT.
|
||||
* The DCT separates the image into a collection of frequencies
|
||||
* and scalars. While JPEG uses an 8x8 DCT, this algorithm uses
|
||||
* a 32x32 DCT.
|
||||
*/
|
||||
const dctVals = applyDCT(vals, this.size);
|
||||
/* 4. Reduce the DCT.
|
||||
* This is the magic step. While the DCT is 32x32, just keep the
|
||||
* top-left 8x8. Those represent the lowest frequencies in the
|
||||
* picture.
|
||||
*/
|
||||
/* 5. Compute the average value.
|
||||
* Like the Average Hash, compute the mean DCT value (using only
|
||||
* the 8x8 DCT low-frequency values and excluding the first term
|
||||
* since the DC coefficient can be significantly different from
|
||||
* the other values and will throw off the average).
|
||||
*/
|
||||
let total = 0;
|
||||
for (let x = 0; x < this.smallerSize; x++) {
|
||||
for (let y = 0; y < this.smallerSize; y++) {
|
||||
total += dctVals[x][y];
|
||||
}
|
||||
}
|
||||
const avg = total / (this.smallerSize * this.smallerSize);
|
||||
/* 6. Further reduce the DCT.
|
||||
* This is the magic step. Set the 64 hash bits to 0 or 1
|
||||
* depending on whether each of the 64 DCT values is above or
|
||||
* below the average value. The result doesn't tell us the
|
||||
* actual low frequencies; it just tells us the very-rough
|
||||
* relative scale of the frequencies to the mean. The result
|
||||
* will not vary as long as the overall structure of the image
|
||||
* remains the same; this can survive gamma and color histogram
|
||||
* adjustments without a problem.
|
||||
*/
|
||||
let hash = "";
|
||||
for (let x = 0; x < this.smallerSize; x++) {
|
||||
for (let y = 0; y < this.smallerSize; y++) {
|
||||
hash += dctVals[x][y] > avg ? "1" : "0";
|
||||
}
|
||||
}
|
||||
return hash;
|
||||
}
|
||||
}
|
||||
// DCT function stolen from http://stackoverflow.com/questions/4240490/problems-with-dct-and-idct-algorithm-in-java
|
||||
/**
|
||||
Convert a 32-bit integer color value to an RGBA object.
|
||||
*/
|
||||
function intToRGBA(i) {
|
||||
const a = i & 0xff;
|
||||
i >>>= 8;
|
||||
const b = i & 0xff;
|
||||
i >>>= 8;
|
||||
const g = i & 0xff;
|
||||
i >>>= 8;
|
||||
const r = i & 0xff;
|
||||
return { r, g, b, a };
|
||||
}
|
||||
const c = [];
|
||||
function initCoefficients(size) {
|
||||
for (let i = 1; i < size; i++) {
|
||||
c[i] = 1;
|
||||
}
|
||||
c[0] = 1 / Math.sqrt(2.0);
|
||||
}
|
||||
function applyDCT(f, size) {
|
||||
const N = size;
|
||||
const F = [];
|
||||
for (let u = 0; u < N; u++) {
|
||||
const row = [];
|
||||
for (let v = 0; v < N; v++) {
|
||||
let sum = 0;
|
||||
for (let i = 0; i < N; i++) {
|
||||
for (let j = 0; j < N; j++) {
|
||||
sum +=
|
||||
Math.cos(((2 * i + 1) / (2.0 * N)) * u * Math.PI) *
|
||||
Math.cos(((2 * j + 1) / (2.0 * N)) * v * Math.PI) *
|
||||
f[i][j];
|
||||
}
|
||||
}
|
||||
sum *= (c[u] * c[v]) / 4;
|
||||
row[v] = sum;
|
||||
F[u] = row;
|
||||
}
|
||||
}
|
||||
return F;
|
||||
}
|
||||
export default ImagePHash;
|
||||
//# sourceMappingURL=phash.js.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"phash.js","sourceRoot":"","sources":["../../src/phash.ts"],"names":[],"mappings":"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"}
|
||||
Reference in new issue
Block a user