use base64::encode;
use lcs_diff::DiffResult;
fn encode_image(pixels: &[u8], precision: f64) -> Vec<String> {
let precision = 1.0 - precision + 0.001;
let precision = if precision <= 0.0 { 1.0 } else { precision };
let chunk_size = pixels.len() as f64 * precision;
let chunk_size = if chunk_size < 1.0 { 1.0 } else { chunk_size };
pixels.chunks(chunk_size as usize).map(encode).collect()
}
pub fn diff(image_a: &[u8], image_b: &[u8], precision: f64) -> f64 {
let encoded_image_a = encode_image(image_a, precision);
let encoded_image_b = encode_image(image_b, precision);
let diff_result = lcs_diff::diff(&encoded_image_a, &encoded_image_b);
let total = diff_result.len() as f64;
let mut changes = 0;
for result in diff_result {
match result {
DiffResult::Added(_) | DiffResult::Removed(_) => changes += 1,
DiffResult::Common(_) => continue,
}
}
f64::from(changes) / total
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn diff_images() {
let image1 = image::open("tests/images/image1.png").expect("Failed to open image!");
let image2 = image::open("tests/images/image2.png").expect("Failed to open image!");
let image3 = image::open("tests/images/image3.png").expect("Failed to open image!");
let val = diff(&image1.to_bytes(), &image2.to_bytes(), 1.0);
println!("{}", val);
let val = diff(&image2.to_bytes(), &image3.to_bytes(), 1.0);
println!("{}", val);
}
}