dithereens
Before (top) and after (bottom) dithering a gradient (uses simple_dither(), i.e. defaults).
Functions and traits for quantizing values with deterministic hash-based error-diffusion.
Quantizing from f64/f32/f16 to u32/u16/u8 without dithering
creates banding. This crate provides deterministic hash-based dithering to
reduce quantization artifacts.
Overview
- Deterministic: Same input with same seed always produces same output.
- Multiple dithering methods: Hash, R2, GoldenRatio for 1D; IGN, SpatialHash, BlueNoise for 2D.
- Single values: [
dither()], [simple_dither()]. - Iterator processing: [
dither_iter()], [simple_dither_iter()]. - In-place operations: [
dither_slice()], [simple_dither_slice()]. - 2D dithering: [
dither_slice_2d()], [simple_dither_slice_2d()] for images. - Custom methods: Use specific dithering algorithms via [
*_with_method()] functions. no_stdsupport: Works in embedded environments.- Generic types:
f32,f64,f16(withnightly_f16feature), or any type implementing [DitherFloat]. - Blue noise: High-quality blue noise dithering (with
blue_noisefeature).
Quick Start
use simple_dither;
let value: f32 = 0.5;
// Dither `value` to `127u8` or `128u8` deterministically.
// The same index and seed will always produce the same result.
let dithered_value: u8 =
simple_dither.clamp as u8;
assert!;
Dithering Methods
1D Methods (for sequential data)
- Hash (default): Fast hash-based dithering
- R2: Low-discrepancy sequence using the R2 sequence
- GoldenRatio: Golden ratio-based sequence
2D Methods (for images)
- InterleavedGradientNoise (IGN): Fast, good quality for real-time graphics
- SpatialHash: Spatial hash function for blue noise-like properties
- BlueNoiseApprox: Approximation combining IGN and SpatialHash
- BlueNoise (requires
blue_noisefeature): True blue noise from precomputed tables
Using Custom Methods
use ;
let value = 0.5f32;
let seed = 42;
// Use different dithering methods
let hash_method = new;
let r2_method = R2new;
let golden_method = new;
let dithered_hash = simple_dither_with_method;
let dithered_r2 = simple_dither_with_method;
let dithered_golden = simple_dither_with_method;
2D Dithering for Images
use ;
// Example: dither a grayscale image
let width = 256;
let height = 256;
let mut pixels: = vec!;
// Use IGN for 2D dithering
let method = new;
simple_dither_slice_2d;
// pixels now contains dithered values
Performance Guide
Benchmarks with 10,000 values:
- Single values: [
dither()], [simple_dither()]. - In-place slice operations: [
dither_slice()], [simple_dither_slice()] (~5.6x faster than iterator methods) - Iterator chains: [
dither_iter()], [simple_dither_iter()], or [DitherIteratorExt] adapters (allocation overhead)
Parallel Processing
Via rayon (enabled by default). With rayon enabled, _iter and
_slice functions use parallel processing automatically for better performance
on large datasets.
no_std Support
This crate supports no_std environments. The libm crate provides a
native round() implementation. Without libm, a manual implementation is
used.
[]
# `no_std`
= { = "0.3", = false }
[]
# Optional: uses `libm`'s `round()` function instead of a manual
# implementation for `no_std`.
= {
version = "0.3",
= false,
= ["libm"]
}
Native f16 Support
Enable the nightly_f16 feature to use native f16 types (requires nightly
Rust):
[]
= { = "0.3", = ["nightly_f16"] }
Blue Noise Support
Enable the blue_noise feature for high-quality blue noise dithering:
[]
= { = "0.3", = ["blue_noise"] }
This adds the BlueNoise struct which provides true blue noise dithering
using a precomputed 256×256×4 table. Note: This increases binary size by ~5MB.
use ;
let width = 256;
let mut pixels: = vec!;
let blue_noise = new;
simple_dither_slice_2d;
License
Apache-2.0 OR BSD-3-Clause OR MIT OR Zlib at your discretion.