1use img_hash::image;
2use img_hash::{HashAlg, HasherConfig};
3use std::path::Path;
4use thiserror::Error;
5
6#[derive(Debug, Error)]
7pub enum PhashError {
8 #[error(transparent)]
9 Image(#[from] image::ImageError),
10 #[error("hash length unexpected")]
11 BadLength,
12}
13
14pub fn phash_u64(path: &Path) -> Result<u64, PhashError> {
16 let img = image::open(path)?;
17 let config = HasherConfig::new()
18 .hash_size(8, 8)
19 .hash_alg(HashAlg::Gradient);
20 let hasher = config.to_hasher();
21 let hash = hasher.hash_image(&img);
22 let bytes = hash.as_bytes();
23 if bytes.len() < 8 {
24 return Err(PhashError::BadLength);
25 }
26 let mut v: u64 = 0;
27 for &b in &bytes[..8] {
28 v = (v << 8) | u64::from(b);
29 }
30 Ok(v)
31}