Last active 1763486415

Revision 75e3f35031e0f708cb757ec59d42c651b7dc3b38

phash.py Raw
1#!/usr/bin/env -S uv run --script
2# /// script
3# requires-python = ">=3.12"
4# dependencies = [
5# "imagehash"
6# ]
7# ///
8
9from PIL import Image
10import imagehash
11import numpy
12
13def from64bit_hash(value: int):
14 """
15 Converts a 64-bit unsigned long integer into an ImageHash object.
16
17 The integer is transformed into a 8x8 binary numpy array, which is the
18 standard representation for many perceptual hashes.
19
20 :param value: The 64-bit integer hash value.
21 Must be between 0 and 2**64 - 1.
22 :return: An ImageHash object representing the integer.
23 """
24 if not (0 <= value < 2**64):
25 raise ValueError("Value must be a 64-bit unsigned integer (between 0 and 2**64 - 1).")
26
27 # 1. Convert the integer to its 64-bit binary string representation.
28 # numpy.binary_repr is perfect for this, as it handles padding.
29 # Example: 1 -> '000...001'
30 binary_string = numpy.binary_repr(value, width=64)
31
32 # 2. Convert the binary string into a numpy array of booleans.
33 # '1' becomes True, '0' becomes False.
34 binary_array = numpy.array([char == '1' for char in binary_string], dtype=bool)
35
36 # 3. Reshape the 64-element flat array into a 8x8 matrix.
37 matrix = binary_array.reshape((8, 8), order='F')
38
39 # 4. Create and return the ImageHash instance.
40 return imagehash.ImageHash(matrix)
41
42if __name__ == '__main__':
43 result = imagehash.phash(Image.open('pepper.png'))
44 result2 = from64bit_hash(15500626565295817037)
45 print(result - result2)