Skip to main content

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-exports imagehash==4.3.2 + adds whash_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


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

rosetta_squint-1.1.2.tar.gz (13.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

rosetta_squint-1.1.2-py3-none-any.whl (9.3 kB view details)

Uploaded Python 3

File details

Details for the file rosetta_squint-1.1.2.tar.gz.

File metadata

  • Download URL: rosetta_squint-1.1.2.tar.gz
  • Upload date:
  • Size: 13.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.3

File hashes

Hashes for rosetta_squint-1.1.2.tar.gz
Algorithm Hash digest
SHA256 79b562effedb1b87321f159beda1a27c1d00beb95a2c28627d2287b88101abfd
MD5 1ccd77907a182e77e91f75826b170d8f
BLAKE2b-256 c4ee5c8af47a7673ed09d627244f35bd6713cb4e720013159c98990bb09c063b

See more details on using hashes here.

File details

Details for the file rosetta_squint-1.1.2-py3-none-any.whl.

File metadata

  • Download URL: rosetta_squint-1.1.2-py3-none-any.whl
  • Upload date:
  • Size: 9.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.3

File hashes

Hashes for rosetta_squint-1.1.2-py3-none-any.whl
Algorithm Hash digest
SHA256 614ce680a4112a0319b1e181649458320191d15af4ea3d77541c8cf4e57bd1b9
MD5 97bf42256a86923c9739ecafef74fa19
BLAKE2b-256 338fb0de34a86f9f4c0968da182df4a5d1405340220e26485b3d44202629a5f8

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page