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.0.0.tar.gz (12.8 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.0.0-py3-none-any.whl (9.0 kB view details)

Uploaded Python 3

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

Hashes for rosetta_squint-1.0.0.tar.gz
Algorithm Hash digest
SHA256 c1a8f92f7c5dd2bdfd6f4f356dc25e9c3eed95751a4bc8786c69f6da88a83ef4
MD5 d8b41249d87f8ab3f2b63e5182efd91b
BLAKE2b-256 1ef5ee41b4a1211af51751f7ccc59841b98280c034d5c44d3e99e4d292aa3fab

See more details on using hashes here.

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

Hashes for rosetta_squint-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 42b408b24d819b8e8b7b45b6f248981c051b420887d15f3b5ad7efdee214b177
MD5 232c850cd50a670a61e0f227a57d6311
BLAKE2b-256 253574986ed8acdd86cc9339059c8c3665e407a10c932f982bf9be10bcf00cc9

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