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.1.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.1-py3-none-any.whl (9.3 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: rosetta_squint-1.1.1.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.1.tar.gz
Algorithm Hash digest
SHA256 475c01f5a0fde9f275f66cdc54ddb4ad7ec0db90eb357f5c850244e0f0e1daf4
MD5 e9be562781db0e9f0a05b1b4b15abe46
BLAKE2b-256 2805caf6bac0aad1737922682a1dd220bd3b4852bc8335493d4a8f08aaba00a2

See more details on using hashes here.

File details

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

File metadata

  • Download URL: rosetta_squint-1.1.1-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.1-py3-none-any.whl
Algorithm Hash digest
SHA256 014f7ccd26f46184ba0a24fd87eac53f91ee5ab1a6286f461e13cca4f7f7005c
MD5 384de151be533325f639d7688f3d775c
BLAKE2b-256 05ff4a432372c921316bea70f8199abce150c9ad66d8f463316085fe4c19cce3

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