close
Skip to Content
New: ssim-native brings SSIM, MS-SSIM and Hitchhiker's to Node, and interpret-native ships diff interpretation on its own. Read more β†’
APIsblazediff

blazediff (Python)

PyO3 bindings to the same Rust core that powers @blazediff/core-native. 3-4x faster than odiffΒ , shipped as abi3 wheels for CPython β‰₯ 3.8 across macOS, Linux, and Windows.

View Detailed BenchmarksΒ 

Installation

pip install blazediff

uv pip install blazediff and poetry add blazediff work identically. Pre-built wheels are published for:

  • macOS ARM64 (Apple Silicon) & x86_64 (Intel)
  • Linux ARM64 & x86_64 (manylinux 2.17)
  • Windows ARM64 & x86_64

A single abi3-py38 wheel per platform serves every CPython β‰₯ 3.8 - no separate wheel per minor version.

Features

  • PNG, JPEG & QOI support - auto-detected by file extension
  • Path-based - pass file paths in, blazediff handles decode + compare + encode
  • SIMD-accelerated - NEON on ARM, SSE4.1 on x86
  • Block-based optimization - skips unchanged regions
  • Interpret mode - region detection, classification, severity scoring, human-readable summaries

API Reference

compare(base_path, compare_path, diff_output=None, *, ...)

Compares two images and optionally writes a diff image. All keyword arguments are optional.

from blazediff import compare result = compare( "expected.png", "actual.png", "diff.png", threshold=0.1, antialiasing=True, )

Parameters

ParameterTypeDefaultDescription
base_pathstr-Path to the base/expected image
compare_pathstr-Path to the comparison/actual image
diff_outputstr | NoneNonePath where the diff image (or HTML report) will be written
thresholdfloat0.1Color difference threshold (0.0-1.0). Lower = stricter
antialiasingboolFalseEnable anti-aliasing detection
diff_maskboolFalseOutput only differences with a transparent background
compressionint0PNG compression level (0-9, 0 = fastest, 9 = smallest)
qualityint90JPEG quality (1-100)

Return value

compare() returns a DiffResult object with:

FieldTypeDescription
matchboolTrue when images are identical (within threshold)
reasonstr | None"layout-diff" or "pixel-diff" when match is False
diff_countint | NoneNumber of differing pixels (pixel-diff only)
diff_percentagefloat | NonePercentage of differing pixels (pixel-diff only)

Threshold guidelines:

  • 0.0 - Exact match only
  • 0.05 - Strict comparison
  • 0.1 - Default balanced comparison
  • 0.2 - Lenient comparison

Usage

Basic comparison

from blazediff import compare result = compare("expected.png", "actual.png", "diff.png", threshold=0.1) if result.match: print("Images are identical!") elif result.reason == "pixel-diff": print(f"{result.diff_count} pixels differ ({result.diff_percentage:.2f}%)") elif result.reason == "layout-diff": print("Images have different dimensions")

pytest assertion

from blazediff import compare def test_homepage_matches_baseline(): result = compare("baseline.png", "rendered.png", "diff.png", threshold=0.05) assert result.match, ( f"{result.diff_count} pixels differ ({result.diff_percentage:.2f}%)" )

Mixed formats

compare() infers format from the file extension. Inputs and outputs can mix freely:

# PNG inputs, QOI diff output (12x smaller diff files) compare("expected.png", "actual.png", "diff.qoi") # JPEG comparison compare("expected.jpg", "actual.jpg", "diff.jpg", quality=85)
FormatExtensionsNotes
PNG.pngLossless, transparency
JPEG.jpg, .jpegLossy, smaller files
QOI.qoiFast lossless, ideal for diff outputs (~12x smaller than PNG)

Interpret mode

Structured analysis β€” change regions, classification (Addition, Deletion, Shift, ContentChange, ColorChange, RenderingNoise), severity scoring and human-readable summaries β€” is not part of the Python wheel. It lives in the blazediff-interpret crate, reachable from a shell with its blazediff-interpret CLI:

blazediff-interpret expected.png actual.png --json

See Interpret example β†’ for the interactive demo.