use average::AverageHasher;
use difference::DifferenceHasher;
use image::ImageError;
use median::MedianHasher;
use perceptual::PerceptualHasher;
use std::path::Path;
pub trait ImageHasher {
fn hash_from_path(&self, path: &Path) -> Result<ImageHash, ImageError> {
match image::ImageReader::open(path)?.decode() {
Ok(img) => Ok(self.hash_from_img(&img)),
Err(e) => Err(e),
}
}
fn hash_from_img(&self, img: &image::DynamicImage) -> ImageHash;
}
pub fn average_hash(path: &Path) -> Result<ImageHash, ImageError> {
let hasher = AverageHasher::default();
hasher.hash_from_path(path)
}
pub fn median_hash(path: &Path) -> Result<ImageHash, ImageError> {
let hasher = MedianHasher::default();
hasher.hash_from_path(path)
}
pub fn difference_hash(path: &Path) -> Result<ImageHash, ImageError> {
let hasher = DifferenceHasher::default();
hasher.hash_from_path(path)
}
pub fn perceptual_hash(path: &Path) -> Result<ImageHash, ImageError> {
let hasher = PerceptualHasher::default();
hasher.hash_from_path(path)
}
pub mod average;
pub mod difference;
pub mod median;
pub mod perceptual;
mod imageops;
mod imghash;
mod math;
pub use crate::imageops::ColorSpace;
pub use crate::imghash::ImageHash;
#[cfg(test)]
mod tests {
use super::*;
const TEST_IMG: &str = "./data/img/test.png";
const TXT_FILE: &str = "./data/misc/test.txt";
#[test]
fn test_average_hash() {
let path = Path::new(TEST_IMG);
let hash = average_hash(path);
assert_eq!(hash.unwrap().encode(), "ffffff0e00000301")
}
#[test]
fn test_average_hash_with_txt_file() {
let path = Path::new(TXT_FILE);
let hash = average_hash(path);
match hash {
Ok(_) => panic!("should not be able to calculate hash for txt file"),
Err(_) => {}
}
}
#[test]
fn test_median_hash() {
let path = Path::new(TEST_IMG);
let hash = median_hash(path);
assert_eq!(hash.unwrap().encode(), "ffffff1e00000301")
}
#[test]
fn test_median_hash_with_txt_file() {
let path = Path::new(TXT_FILE);
let hash = median_hash(path);
match hash {
Ok(_) => panic!("should not be able to calculate hash for txt file"),
Err(_) => {}
}
}
#[test]
fn test_difference_hash() {
let path = Path::new(TEST_IMG);
let hash = difference_hash(path);
assert_eq!(hash.unwrap().encode(), "cc99717ed9ea0627")
}
#[test]
fn test_difference_hash_with_txt_file() {
let path = Path::new(TXT_FILE);
let hash = difference_hash(path);
match hash {
Ok(_) => panic!("should not be able to calculate hash for txt file"),
Err(_) => {}
}
}
#[test]
fn test_perceptual_hash() {
let path = Path::new(TEST_IMG);
let hash = perceptual_hash(path);
assert_eq!(hash.unwrap().encode(), "acdbe86135344e3a")
}
#[test]
fn test_perceptual_hash_with_txt_file() {
let path = Path::new(TXT_FILE);
let hash = perceptual_hash(path);
match hash {
Ok(_) => panic!("should not be able to calculate hash for txt file"),
Err(_) => {}
}
}
}