Cross-language byte-exact perceptual image hashing — decode + hash in one call
Project description
rosetta_squint — Python convenience API
Point at an image file or pass in raw image bytes; get back the same perceptual hash hex string that every other rosetta-squint port produces for the same input.
Install
pip install -e ../../hash/python # rosetta-squint-hash (wrapper around imagehash)
pip install -e . # this package
(Not on PyPI yet — both are local.)
Usage
import rosetta_squint as rs
# Path on disk
h = rs.phash("photo.jpg", 8)
print(h) # "c3f8a1b27d0e4f96"
# Raw image bytes (from an HTTP response, a database BLOB, a multipart upload)
with open("photo.jpg", "rb") as f:
h = rs.phash_bytes(f.read(), 8)
# Every algorithm available has both flavors:
rs.average_hash(path, 8) # rs.average_hash_bytes(bytes, 8)
rs.phash(path, 8) # rs.phash_bytes(bytes, 8)
rs.phash_simple(path, 8) # rs.phash_simple_bytes(bytes, 8)
rs.dhash(path, 8) # rs.dhash_bytes(bytes, 8)
rs.dhash_vertical(path, 8) # rs.dhash_vertical_bytes(bytes, 8)
rs.whash_haar(path, 8) # rs.whash_haar_bytes(bytes, 8)
rs.whash_db4(path, 8) # rs.whash_db4_bytes(bytes, 8)
rs.whash_db4_robust(path, 8) # rs.whash_db4_robust_bytes(bytes, 8) — cross-port-stable
rs.colorhash(path, 3) # rs.colorhash_bytes(bytes, 3) — takes binbits
rs.crop_resistant_hash(path) # rs.crop_resistant_hash_bytes(bytes) — no size, returns ImageMultiHash
# Hex round-trips:
restored = rs.hex_to_hash("c3f8a1b27d0e4f96")
restored = rs.hex_to_flathash("...", hashsize=3)
restored = rs.hex_to_multihash("hex1,hex2,hex3")
Cross-port equivalence
The output of rs.phash("photo.jpg", 8) is the same hex string as you'd get from the Rust, Go, Java, JS, or Swift rosetta-squint ports given the same byte input. Verified live for imagehash.png at size 8: ba8c84536bd3c366 across Python, Go, Java, JS, Swift.
Decode strategy
| Format | Decoder | Why |
|---|---|---|
| BMP, PNG, GIF, JPEG, WebP, TIFF | PIL/Pillow (system) | The canonical Python decoders; the goldens used to validate the 5 native ports were generated by PIL itself, so output matches by construction. |
| HEIC | ctypes wrapper around system libheif.so.1 |
pillow-heif bundles libheif 1.21.2 in its wheel; the 5 native ports link to system libheif 1.17.6. The wrapper avoids the ±1 px divergence. |
If you already have a PIL.Image.Image (from PIL.Image.open(...), a thumbnailer, etc.), use the rosetta_squint_hash lower-level API directly — the squint layer's only job is the decode step:
import rosetta_squint_hash as rih
from PIL import Image
img = Image.open("photo.jpg")
h = rih.phash(img, hash_size=8)
Dependencies
rosetta_squint_hash(which re-exportsimagehash==4.3.2+ addswhash_db4_robust)Pillow==12.2.*
Tight pins are intentional. See ../../hash/python/README.md under "Version policy" for the upgrade workflow.
Testing
pytest
Tests verify (1) path/bytes parity for every algorithm, (2) chain consistency between rs.phash(path) and imagehash.phash(rs.decode_file(path)), (3) cross-port byte-exact equality with Go/Java/JS for imagehash.png.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file rosetta_squint-1.0.0.tar.gz.
File metadata
- Download URL: rosetta_squint-1.0.0.tar.gz
- Upload date:
- Size: 12.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c1a8f92f7c5dd2bdfd6f4f356dc25e9c3eed95751a4bc8786c69f6da88a83ef4
|
|
| MD5 |
d8b41249d87f8ab3f2b63e5182efd91b
|
|
| BLAKE2b-256 |
1ef5ee41b4a1211af51751f7ccc59841b98280c034d5c44d3e99e4d292aa3fab
|
File details
Details for the file rosetta_squint-1.0.0-py3-none-any.whl.
File metadata
- Download URL: rosetta_squint-1.0.0-py3-none-any.whl
- Upload date:
- Size: 9.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
42b408b24d819b8e8b7b45b6f248981c051b420887d15f3b5ad7efdee214b177
|
|
| MD5 |
232c850cd50a670a61e0f227a57d6311
|
|
| BLAKE2b-256 |
253574986ed8acdd86cc9339059c8c3665e407a10c932f982bf9be10bcf00cc9
|