Skip to main content

Rust-accelerated pixelmatch and SSIM for PNG bytes

Project description

pixelhog

Fast visual regression primitives for Python, implemented in Rust.

pixelhog compares screenshots in two complementary ways:

  • diff: exact pixel-level differences (with anti-alias handling), optional diff image output
  • ssim: perceptual similarity score in [0.0, 1.0]

Install (local dev)

uv venv .venv --python 3.12
source .venv/bin/activate
uv pip install -U pip maturin
maturin develop --release

Quickstart

from pixelhog import diff, ssim, compare

# 1) Pixel-level diff + diff PNG
# returns: (diff_png_bytes, diff_count, width, height)
diff_png, diff_count, width, height = diff(baseline_png, current_png)

# 2) Perceptual similarity
score = ssim(baseline_png, current_png)

# 3) One-call gate (count + SSIM), no diff image encoding overhead
# returns: (diff_count, ssim, width, height, maybe_diff_png)
diff_count, score, width, height, _ = compare(
    baseline_png,
    current_png,
    return_diff=False,
)

API at a glance

Function Input Output Use when
diff PNG bytes (diff_png, diff_count, width, height) You need a visual diff artifact
diff_count PNG bytes (diff_count, width, height) You only need the mismatch count
ssim PNG bytes float You need perceptual similarity
compare PNG bytes (diff_count, ssim, width, height, optional_diff_png) You want both metrics in one call
diff_rgba RGBA bytes + sizes (diff_rgba, diff_count, width, height) You already decoded images in Python/Rust
diff_count_rgba RGBA bytes + sizes (diff_count, width, height) Count-only on pre-decoded buffers
ssim_rgba RGBA bytes + sizes float SSIM on pre-decoded buffers
compare_rgba RGBA bytes + sizes (diff_count, ssim, width, height, optional_diff_rgba) Combined metrics on pre-decoded buffers
diff_batch list[(baseline_png, current_png)] list[diff result] Run many diffs in one call
diff_count_batch list[(baseline_png, current_png)] list[count result] Batch count-only checks
ssim_batch list[(baseline_png, current_png)] list[float] Batch SSIM checks
compare_batch list[(baseline_png, current_png)] list[compare result] Batch combined checks

Behavior

  • High-level APIs accept PNG bytes and decode internally.
  • Smaller images are padded to the larger dimensions with transparent pixels.
  • diff always generates a diff image.
  • diff_count and compare(..., return_diff=False) skip diff-image generation.
  • SSIM uses 11x11 uniform windows with reflect padding.
  • For images smaller than 11x11, SSIM falls back to global SSIM.
  • No SSIM visualization image is produced.

Correctness and tests

The test suite is designed to validate both algorithm fidelity and practical product behavior.

  • Rust unit/integration tests cover:
    • identical/completely different/partial-diff images
    • threshold behavior
    • different-size padding behavior
    • SSIM behavior (identical, slight change, large change, small-image fallback)
  • Canonical pixelmatch fixture tests use the official Mapbox test set:
    • 8 fixture pairs with exact expected mismatch counts
    • expected diff image comparison against golden outputs
    • decoded RGBA byte equality checks to ensure pixel-perfect output matching
  • Python integration tests cover:
    • high-level API contracts and error behavior
    • tall-page and subtle-change scenarios
    • cross-validation against a pure-Python reference implementation
      • pixel diff counts must match exactly
      • SSIM must stay within tolerance

Run the full correctness suite:

# Rust core only
cargo test -p pixelhog

# Full suite including Python integration tests
cargo test
uv run --python 3.12 --with maturin --with pytest --with pillow bash -lc \
  "maturin develop --release && pytest -q"

Benchmarks

The repo includes both Criterion benches and pipeline breakdown tools.

  • cargo bench runs Criterion API benchmarks (PNG-bytes entry points).
  • Breakdown binaries in examples/ measure where time goes:
    • breakdown.rs: decode vs core diff vs encode vs API call
    • ssim_breakdown.rs: decode/pad vs core SSIM vs API call
    • combined_estimate.rs: separate calls vs combined single-decode flow

Run:

cargo bench -p pixelhog
cargo run -p pixelhog --release --example breakdown
cargo run -p pixelhog --release --example ssim_breakdown
cargo run -p pixelhog --release --example combined_estimate

For screenshot-style workloads, the practical guidance is:

  • diff_count is cheaper than diff when you do not need an artifact.
  • compare(..., return_diff=False) avoids duplicate decode work when you need both diff-count and SSIM.

Development

# Rust tests (includes canonical Mapbox fixture tests)
cargo test

# Python extension + tests
uv run --python 3.12 --with maturin --with pytest --with pillow bash -lc \
  "maturin develop --release && pytest -q"

# Lint/format/type-check
uv run --python 3.12 --with ruff ruff format --check .
uv run --python 3.12 --with ruff ruff check .
uv run --python 3.12 --with ty --with pytest --with pillow ty check . --python .venv

License

This repository is MIT licensed. See LICENSE.

Algorithm attribution for pixelmatch is documented in THIRD_PARTY_NOTICES.md.

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

pixelhog-1.0.0.tar.gz (20.3 kB view details)

Uploaded Source

Built Distributions

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

pixelhog-1.0.0-cp312-abi3-win_amd64.whl (390.3 kB view details)

Uploaded CPython 3.12+Windows x86-64

pixelhog-1.0.0-cp312-abi3-musllinux_1_2_x86_64.whl (702.7 kB view details)

Uploaded CPython 3.12+musllinux: musl 1.2+ x86-64

pixelhog-1.0.0-cp312-abi3-musllinux_1_2_aarch64.whl (648.1 kB view details)

Uploaded CPython 3.12+musllinux: musl 1.2+ ARM64

pixelhog-1.0.0-cp312-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (506.5 kB view details)

Uploaded CPython 3.12+manylinux: glibc 2.17+ x86-64

pixelhog-1.0.0-cp312-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (471.8 kB view details)

Uploaded CPython 3.12+manylinux: glibc 2.17+ ARM64

pixelhog-1.0.0-cp312-abi3-macosx_11_0_arm64.whl (441.5 kB view details)

Uploaded CPython 3.12+macOS 11.0+ ARM64

pixelhog-1.0.0-cp312-abi3-macosx_10_12_x86_64.whl (453.3 kB view details)

Uploaded CPython 3.12+macOS 10.12+ x86-64

File details

Details for the file pixelhog-1.0.0.tar.gz.

File metadata

  • Download URL: pixelhog-1.0.0.tar.gz
  • Upload date:
  • Size: 20.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.6 {"installer":{"name":"uv","version":"0.11.6","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for pixelhog-1.0.0.tar.gz
Algorithm Hash digest
SHA256 c52eb35d02dffd539f9c9570ad8b06f514f14287583036ea92c37227f6c90d74
MD5 9ac223fd1753725fc965bdd148438a48
BLAKE2b-256 d956f462f024d9342a8c22edc319c4ef69eccce1067f571120ac7b9985aefeba

See more details on using hashes here.

File details

Details for the file pixelhog-1.0.0-cp312-abi3-win_amd64.whl.

File metadata

  • Download URL: pixelhog-1.0.0-cp312-abi3-win_amd64.whl
  • Upload date:
  • Size: 390.3 kB
  • Tags: CPython 3.12+, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.6 {"installer":{"name":"uv","version":"0.11.6","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for pixelhog-1.0.0-cp312-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 12f09811f77d9d5b364926cc128db423dea01781e586006ed4450c54e9adab1d
MD5 f02c5e5e4a648800f64bb12a08282e53
BLAKE2b-256 83b1f01f99bcfdf16d4a1dc55b5c0c2bebc70df76cacaa065ba569201da14d5c

See more details on using hashes here.

File details

Details for the file pixelhog-1.0.0-cp312-abi3-musllinux_1_2_x86_64.whl.

File metadata

  • Download URL: pixelhog-1.0.0-cp312-abi3-musllinux_1_2_x86_64.whl
  • Upload date:
  • Size: 702.7 kB
  • Tags: CPython 3.12+, musllinux: musl 1.2+ x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.6 {"installer":{"name":"uv","version":"0.11.6","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for pixelhog-1.0.0-cp312-abi3-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 091a3f222e0792efdae5e5170ed89e95ccc264a6486d5529dd9fddd97e32baf1
MD5 bf153f5928621b4fa5431b158618e905
BLAKE2b-256 3b20e636acaaa82f34817567579311857095d4acd2353f2cad5f2e518b1dc8d7

See more details on using hashes here.

File details

Details for the file pixelhog-1.0.0-cp312-abi3-musllinux_1_2_aarch64.whl.

File metadata

  • Download URL: pixelhog-1.0.0-cp312-abi3-musllinux_1_2_aarch64.whl
  • Upload date:
  • Size: 648.1 kB
  • Tags: CPython 3.12+, musllinux: musl 1.2+ ARM64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.6 {"installer":{"name":"uv","version":"0.11.6","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for pixelhog-1.0.0-cp312-abi3-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 20e73ad915e25229cf41dc637a9ea81dc55cecdb4ec16ef6467e2d18127fb2ba
MD5 09c5998916149b4ecf4fb2f68dab2b4e
BLAKE2b-256 08b5602e77e784e39061a2fd10e3ae8d57566861b94d19f3c1191341caac3b2a

See more details on using hashes here.

File details

Details for the file pixelhog-1.0.0-cp312-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

  • Download URL: pixelhog-1.0.0-cp312-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
  • Upload date:
  • Size: 506.5 kB
  • Tags: CPython 3.12+, manylinux: glibc 2.17+ x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.6 {"installer":{"name":"uv","version":"0.11.6","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for pixelhog-1.0.0-cp312-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 b69cacd91f7286084ff787f14ccc208e13ab337c13ba63ea52a738b84ee93863
MD5 da8dbfbc3dcc5a4dcc56cabf3f2d8440
BLAKE2b-256 2f4f3d191ce7e1874dd51bea8e0daed075c237f59680dd53464f6db70eeeb36b

See more details on using hashes here.

File details

Details for the file pixelhog-1.0.0-cp312-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

  • Download URL: pixelhog-1.0.0-cp312-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
  • Upload date:
  • Size: 471.8 kB
  • Tags: CPython 3.12+, manylinux: glibc 2.17+ ARM64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.6 {"installer":{"name":"uv","version":"0.11.6","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for pixelhog-1.0.0-cp312-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 6e706c23e9c7a58c38fbad531380cc5f7de22f5d4dd9d209b4f3af6b3778f165
MD5 6ff793db2553e8a06969f218f7eee838
BLAKE2b-256 acfa557469fafd80389e077fabc16d80e9034bdf8cf78cddc30fcc80265c463f

See more details on using hashes here.

File details

Details for the file pixelhog-1.0.0-cp312-abi3-macosx_11_0_arm64.whl.

File metadata

  • Download URL: pixelhog-1.0.0-cp312-abi3-macosx_11_0_arm64.whl
  • Upload date:
  • Size: 441.5 kB
  • Tags: CPython 3.12+, macOS 11.0+ ARM64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.6 {"installer":{"name":"uv","version":"0.11.6","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for pixelhog-1.0.0-cp312-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 9c0c08067e14ea3baeadaf0cc830d5fa0829b69ab6be9f99a74b807e877958ec
MD5 7a78dd97252de0d1e3813ce7bf03a8eb
BLAKE2b-256 d44aa7053f4c590fa337c601de2af7ce43beea7a95c7429d18dabe3160f4d5a0

See more details on using hashes here.

File details

Details for the file pixelhog-1.0.0-cp312-abi3-macosx_10_12_x86_64.whl.

File metadata

  • Download URL: pixelhog-1.0.0-cp312-abi3-macosx_10_12_x86_64.whl
  • Upload date:
  • Size: 453.3 kB
  • Tags: CPython 3.12+, macOS 10.12+ x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.6 {"installer":{"name":"uv","version":"0.11.6","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for pixelhog-1.0.0-cp312-abi3-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 6809cdb8242e7f934adaad8c1849ee6a2da75a84b8ed7b7648b693c7ee023dea
MD5 cbcbecd6515b5432181b49dd75f71f91
BLAKE2b-256 5e91b5f58c8abc2f931a8f3b298148ee66f8ea1bfde0371a23fd792172091b34

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