* Returns a 'binary string' (like. 001010111011100010) which is easy to do a hamming distance on.
(img: JimpClass)
| 59 | * Returns a 'binary string' (like. 001010111011100010) which is easy to do a hamming distance on. |
| 60 | */ |
| 61 | getHash(img: JimpClass) { |
| 62 | /* 1. Reduce size. |
| 63 | * Like Average Hash, pHash starts with a small image. |
| 64 | * However, the image is larger than 8x8; 32x32 is a good size. |
| 65 | * This is really done to simplify the DCT computation and not |
| 66 | * because it is needed to reduce the high frequencies. |
| 67 | */ |
| 68 | img = methods.resize(clone(img), { w: this.size, h: this.size }); |
| 69 | |
| 70 | /* 2. Reduce color. |
| 71 | * The image is reduced to a grayscale just to further simplify |
| 72 | * the number of computations. |
| 73 | */ |
| 74 | img = color.greyscale(img); |
| 75 | |
| 76 | const vals = []; |
| 77 | |
| 78 | for (let x = 0; x < img.bitmap.width; x++) { |
| 79 | const row = []; |
| 80 | for (let y = 0; y < img.bitmap.height; y++) { |
| 81 | row[y] = intToRGBA(img.getPixelColor(x, y)).b; |
| 82 | } |
| 83 | vals[x] = row; |
| 84 | } |
| 85 | |
| 86 | /* 3. Compute the DCT. |
| 87 | * The DCT separates the image into a collection of frequencies |
| 88 | * and scalars. While JPEG uses an 8x8 DCT, this algorithm uses |
| 89 | * a 32x32 DCT. |
| 90 | */ |
| 91 | const dctVals = applyDCT(vals, this.size); |
| 92 | |
| 93 | /* 4. Reduce the DCT. |
| 94 | * This is the magic step. While the DCT is 32x32, just keep the |
| 95 | * top-left 8x8. Those represent the lowest frequencies in the |
| 96 | * picture. |
| 97 | */ |
| 98 | /* 5. Compute the average value. |
| 99 | * Like the Average Hash, compute the mean DCT value (using only |
| 100 | * the 8x8 DCT low-frequency values and excluding the first term |
| 101 | * since the DC coefficient can be significantly different from |
| 102 | * the other values and will throw off the average). |
| 103 | */ |
| 104 | let total = 0; |
| 105 | |
| 106 | for (let x = 0; x < this.smallerSize; x++) { |
| 107 | for (let y = 0; y < this.smallerSize; y++) { |
| 108 | total += dctVals[x]![y]!; |
| 109 | } |
| 110 | } |
| 111 | |
| 112 | const avg = total / (this.smallerSize * this.smallerSize); |
| 113 | |
| 114 | /* 6. Further reduce the DCT. |
| 115 | * This is the magic step. Set the 64 hash bits to 0 or 1 |
| 116 | * depending on whether each of the 64 DCT values is above or |
| 117 | * below the average value. The result doesn't tell us the |
| 118 | * actual low frequencies; it just tells us the very-rough |
no test coverage detected