Blue Noise
August 6, 2026 ยท View on GitHub
Blue Noise
Black and white image dithering using blue noise, plus a void-and-cluster generator for the noise itself
Turn a photograph into two colors without the crosshatch of an ordered dither.
Install
cargo add blue-noise
Quickstart
use blue_noise::{
BlueNoiseConfig, BlueNoiseGenerator, BlueNoiseTexture, Color, DitherOptions, apply_dithering,
save_blue_noise_to_png,
};
fn main() -> Result<(), Box<dyn std::error::Error>> {
let config = BlueNoiseConfig {
width: 64,
height: 64,
seed: Some(42),
..Default::default()
};
let result = BlueNoiseGenerator::new(config)?.generate()?;
save_blue_noise_to_png(&result, "blue-noise.png")?;
let noise = BlueNoiseTexture::load("blue-noise.png")?;
apply_dithering(
"photo.jpg",
"photo-dithered.png",
&noise,
DitherOptions {
foreground: Color::from_hex("#1447e5")?,
contrast: Some(1.2),
..Default::default()
},
)?;
Ok(())
}
apply_dithering_to_image takes and returns an in-memory image if you would rather not touch the filesystem.
CLI
cargo install blue-noise
# Write a 128 by 128 tileable texture to blue-noise.png
blue-noise generate --size 128 --verbose
# Threshold a photo against it
blue-noise dither -i photo.jpg -o photo-dithered.png
| Flag | Default | Description |
|---|---|---|
--sigma <f32> | 1.9 | Gaussian sigma, higher spreads points further apart |
--seed <u32> | Seed for a reproducible texture | |
--noise <path> | blue-noise.png | Texture the dither thresholds against |
--contrast <f32> | Contrast adjustment, above 1 for more |
--width and --height override --size for a non-square texture, and resize the output when dithering. Full lists are in blue-noise generate --help and blue-noise dither --help.
Notes
- Distances wrap at the edges, so a texture tiles seamlessly across an image of any size.
- Power-of-two sizes run their Gaussian blur through an FFT, roughly halving generation time. Generate once and reuse the file.
- Uses the void-and-cluster algorithm from Ulichney (1993), building on Ulichney (1988).
- blue-noise-typescript is the same dithering as a Node CLI, published on npm.
- API documentation is on docs.rs.
License
MIT
Crafted by
Matthew Blode