diff options
| author | ache <ache@ache.one> | 2025-04-27 00:23:13 +0200 |
|---|---|---|
| committer | ache <ache@ache.one> | 2025-04-27 00:23:13 +0200 |
| commit | 256a231cf334aff0ef539fd2c9821314acc645b3 (patch) | |
| tree | ff082802525501d77d1afa77677a70ef687b74cc | |
| parent | Implement serpentine scanning (diff) | |
Implement bayer matrix dithering
| -rw-r--r-- | src/lib.rs | 59 |
1 files changed, 59 insertions, 0 deletions
@@ -137,6 +137,7 @@ fn dither_float_chose_color(diffused_error: f32, pixel: f32) -> (u8, f32) { (255, distance_to_white) } } + #[inline] fn threshold_1b(pix: u8) -> u8 { if pix > 128 { 255 } else { 0 } @@ -417,6 +418,7 @@ pub fn dither_linear(image: &mut RgbImage, kernel: kernel::Kernel) { *pixel_ = image::Rgb([pixel, pixel, pixel]); } } + pub fn dither(image: &mut RgbImage, kernel: kernel::Kernel) { let (width, _height) = image.dimensions(); let width = width as usize; @@ -828,3 +830,60 @@ pub fn dither_palette_linear(image: &mut RgbImage, palette: &[Rgb<u8>], kernel: *pixel = pixel_nearest; } } + +pub fn bayer_matrix(n: u32) -> Vec<Vec<f32>> { + if n == 1 { + return vec![vec![0.]]; + } + let n_square = (n * n) as f32; + + let base_bayer_matrix = bayer_matrix(n >> 1); + + let first: Vec<Vec<f32>> = base_bayer_matrix + .iter() + .map(|x| x.iter().map(|x| x * n_square).collect()) + .collect(); + let mut second: Vec<Vec<f32>> = base_bayer_matrix + .iter() + .map(|x| x.iter().map(|x| x * n_square + 2.).collect()) + .collect(); + + let third: Vec<Vec<f32>> = base_bayer_matrix + .iter() + .map(|x| x.iter().map(|x| x * n_square + 3.).collect()) + .collect(); + + let fourth: Vec<Vec<f32>> = base_bayer_matrix + .iter() + .map(|x| x.iter().map(|x| x * n_square + 1.).collect()) + .collect(); + + let mut first_col = first.to_vec(); + first_col.extend(third); + second.extend(fourth); + + let mut ret = Vec::new(); + + for (f, s) in first_col.iter().zip(second.iter()) { + let mut vec: Vec<f32> = f.to_vec(); + vec.extend(s.to_vec()); + for i in &mut vec { + *i *= 1. / n_square; + } + ret.push(vec) + } + + ret +} + +pub fn dither_bayer(n: u32, image: &mut RgbImage) { + let bayer = bayer_matrix(n as u32); + let (mx, my) = (bayer.len() as usize, bayer[0].len() as usize); + + for (x, y, pixel_) in &mut image.enumerate_pixels_mut() { + let pixel = (255. * bayer[x as usize % my][y as usize % mx]) as u8; + for c in &mut pixel_.0 { + *c = if *c > pixel { 255 } else { 0 }; + } + } +} |