From 322a951d51ce8b13ab5ec1b3cab35bbf92922e75 Mon Sep 17 00:00:00 2001 From: Jurn Wubben Date: Thu, 25 Sep 2025 21:26:07 +0200 Subject: [PATCH] Changing the dithering algorithm --- src/dithering.rs | 56 ++++++++++++++++++++---------------------------- 1 file changed, 23 insertions(+), 33 deletions(-) diff --git a/src/dithering.rs b/src/dithering.rs index 8006276..cb25727 100644 --- a/src/dithering.rs +++ b/src/dithering.rs @@ -1,45 +1,35 @@ -use image::DynamicImage; +use image::{DynamicImage, imageops}; pub fn atkinson_mono(img: &DynamicImage) -> Vec { let mut gray = img.to_luma8(); + imageops::dither(&mut gray, &imageops::colorops::BiLevel); + let (w, h) = (gray.width() as usize, gray.height() as usize); - let pitch = (w + 7) >> 3; - let mut bits = vec![0u8; pitch * h]; - let buf = gray.as_mut(); + let stride = (w + 7) >> 3; + let mut bits = vec![0u8; stride * h]; + let pix = gray.as_raw(); for y in 0..h { - let row = y * w; - for x in 0..w { - let i = row + x; - let old = buf[i]; - let new = if old < 128 { 0 } else { 255 }; - buf[i] = new; - let bit = new == 0; - if bit { - let byte = y * pitch + (x >> 3); - bits[byte] |= 128 >> (x & 7); - } - let err = ((old as i16) - (new as i16)) / 8; + let row_off = y * w; + let bit_off = y * stride; + let chunks = w >> 3; + let tail = w & 7; - if x + 1 < w { - buf[i + 1] = (buf[i + 1] as i16 + err).clamp(0, 255) as u8; + for x8 in 0..chunks { + let p = &pix[row_off + (x8 << 3)..][..8]; + let mut byte = 0u8; + for (bit, &v) in p.iter().enumerate() { + byte |= ((v < 128) as u8) << (7 - bit); } - if x + 2 < w { - buf[i + 2] = (buf[i + 2] as i16 + err).clamp(0, 255) as u8; - } - if y + 1 < h { - let down = i + w; - if x > 0 { - buf[down - 1] = (buf[down - 1] as i16 + err).clamp(0, 255) as u8; - } - buf[down] = (buf[down] as i16 + err).clamp(0, 255) as u8; - if x + 1 < w { - buf[down + 1] = (buf[down + 1] as i16 + err).clamp(0, 255) as u8; - } - if y + 2 < h { - buf[down + w] = (buf[down + w] as i16 + err).clamp(0, 255) as u8; - } + bits[bit_off + x8] = byte; + } + + if tail != 0 { + let mut last = 0u8; + for (bit, &v) in pix[row_off + (chunks << 3)..][..tail].iter().enumerate() { + last |= ((v < 128) as u8) << (7 - bit); } + bits[bit_off + chunks] = last; } } bits