diffimg 2.1.0

Compute the amount of difference between two images
Documentation
// Copyright (c) 2020 Kevin Del Castillo Ramírez
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT

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()
}

/// Compute the amount of difference between two images using their raw bytes.
///
/// Receives two `&[u8]` (the raw bytes of the images to be compared)
/// and returns a `f64` between 0 and 1, representing how much both images
/// differ from each other, where 0 means they are completely equal and 1 means
/// they are completely different. Presicion value goes from 0 to 1 and determines
/// the number of chunks that is going to be used.
///
/// # Example
/// ```no_run
/// use image::*; // To get raw-pixels
/// use diffimg;
///
/// 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 diff = diffimg::diff(&image1.to_bytes(), &image2.to_bytes());
/// ```
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);
    }
}