Browse Source

Working on resolvoing development repository vs published repository differences

develop
Drew Short 7 years ago
parent
commit
78bbb520f9
  1. 16
      Cargo.toml
  2. 32
      src/cache.rs
  3. 12
      src/hash/phash.rs
  4. 51
      src/lib.rs
  5. 10
      src/main.rs

16
Cargo.toml

@ -1,6 +1,6 @@
[package]
name = "pihash"
version = "0.3.4"
version = "0.3.5"
authors = ["Drew Short <warrick@sothr.com>"]
description = "A simple library for generating perceptual hashes for images and comparing images based on their perceptual hashes."
repository = "https://github.com/warricksothr/Perceptual-Image-Hashing/"
@ -20,13 +20,11 @@ default = []
bench = []
[dependencies]
libc = "0.2.17"
rustc-serialize = "0.3.19"
dft = "0.5.2"
image = "0.10.3"
libc = "0.2.20"
rustc-serialize = "0.3.22"
dft = "0.5.4"
image = "0.13.0"
num = "0.1.36"
docopt = "0.6.86"
flate2 = "0.2.14"
docopt = "0.7.0"
flate2 = "0.2.19"
sha1 = "0.2.0"
#criterion = { git = "https://github.com/japaric/criterion.rs" }
log = "0.3.6"

32
src/cache.rs

@ -139,8 +139,9 @@ impl<'a> Cache<'a> {
try!(source.read_to_end(&mut buf));
let mut sha1 = Sha1::new();
sha1.update(&buf);
let digest = sha1.digest();
// Return the hex result of the hash
Ok(sha1.digest().to_string())
Ok(format!("{}", digest))
}
/**
@ -252,11 +253,10 @@ impl<'a> Cache<'a> {
let mut compressor = ZlibEncoder::new(Vec::new(),
Compression::Default);
for row in file_contents {
let mut row_str = row.iter().fold(String::new(),
|acc, &item| {
acc +
&format!("{},", item)
});
let mut row_str =
row.iter()
.fold(String::new(),
|acc, &item| acc + &format!("{},", item));
// remove the last comma
let desire_len = row_str.len() - 1;
row_str.truncate(desire_len);
@ -318,17 +318,15 @@ impl<'a> Cache<'a> {
}
};
// convert the matrix
let matrix: Vec<Vec<f64>> = matrix_data_str.trim()
.split("\n")
.map(|line| {
line.split(",")
.map(|f| {
f64::from_str(f)
.unwrap()
})
.collect()
})
.collect();
let matrix: Vec<Vec<f64>> = matrix_data_str
.trim()
.split("\n")
.map(|line| {
line.split(",")
.map(|f| f64::from_str(f).unwrap())
.collect()
})
.collect();
Some(matrix)
}

12
src/hash/phash.rs

@ -50,8 +50,12 @@ impl<'a> PerceptualHash for PHash<'a> {
None => {
let matrix = create_data_matrix(width, height, &image);
// Store this DFT in the cache
<<<<<<< HEAD
match c.put_matrix_in_cache(&Path::new(self.prepared_image
.orig_path),
=======
match c.put_matrix_in_cache(&Path::new(self.prepared_image.orig_path),
>>>>>>> master
width as u32,
&matrix) {
Ok(_) => {}
@ -82,19 +86,15 @@ impl<'a> PerceptualHash for PHash<'a> {
// Calculating a hash based on the mean
let mut hash = 0u64;
for x in 0..target_width {
// println!("Mean: {} Values: {:?}",mean,data_matrix[x]);
for y in 0..target_height {
if data_matrix[x][y] >= mean {
hash |= 1;
// println!("Pixel {} is >= {} therefore {:b}", pixel_sum, mean, hash);
} else {
hash |= 0;
// println!("Pixel {} is < {} therefore {:b}", pixel_sum, mean, hash);
}
hash <<= 1;
}
}
// println!("Hash for {} is {}", prepared_image.orig_path, hash);
hash
}
None => 0u64,
@ -113,8 +113,12 @@ fn create_data_matrix(width: usize,
for y in 0..height {
let pos_x = x as u32;
let pos_y = y as u32;
<<<<<<< HEAD
data_matrix[x].push(image.get_pixel(pos_x, pos_y)
.channels()[0] as f64);
=======
data_matrix[x].push(image.get_pixel(pos_x, pos_y).channels()[0] as f64);
>>>>>>> master
}
}

51
src/lib.rs

@ -25,9 +25,15 @@ pub struct PIHash<'a> {
impl<'a> PIHash<'a> {
/**
<<<<<<< HEAD
* Create a new pihash library, and initialize a cache of a path is passed.
* If none is passed then no cache is initialized or used with the library
*/
=======
* Create a new pihash library, and initialize a cache of a path is passed.
* If none is passed then no cache is initialized or used with the library
*/
>>>>>>> master
pub fn new(cache_path: Option<&'a str>) -> PIHash<'a> {
match cache_path {
Some(path) => {
@ -180,7 +186,7 @@ fn to_hex_string(bytes: &[u8]) -> String {
// Module for the tests
//
#[cfg(test)]
#[cfg(test)]
mod tests {
use std::fs;
@ -202,18 +208,18 @@ mod tests {
Some(_) => {
if ext.unwrap() == "jpg" {
num_paths += 1;
println!("Is a image {}: {:?}", num_paths, orig_path) ;
println!("Is a image {}: {:?}", num_paths, orig_path);
}
}
_ => {
println!("Not an image: {:?}", orig_path) ;
println!("Not an image: {:?}", orig_path);
continue;
}
}
// println!("Name: {}", path.unwrap().path().display())
}
// Currently 12 images in the test imaages directory
assert!(num_paths == 12);
// Currently 12 images in the test images directory
assert_eq!(num_paths, 12);
}
/**
@ -234,7 +240,7 @@ mod tests {
image_path.to_str().unwrap(),
image_hashes[index],
calculated_hash);
assert!(calculated_hash == image_hashes[index]);
assert_eq!(calculated_hash, image_hashes[index]);
hashes[index] = calculated_hash;
}
@ -244,8 +250,7 @@ mod tests {
continue;
} else {
let distance = hash::calculate_hamming_distance(hashes[index], hashes[index2]);
println!("Hashes [{}] and [{}] have a hamming distance of [{}] of a max \
allowed distance of [{}]",
println!("Hashes [{}] and [{}] have a hamming distance of [{}] of a max allowed distance of [{}]",
hashes[index],
hashes[index2],
distance,
@ -291,9 +296,8 @@ mod tests {
let sample_03_images: [&Path; 3] = [&Path::new("./test_images/sample_03_large.jpg"),
&Path::new("./test_images/sample_03_medium.jpg"),
&Path::new("./test_images/sample_03_small.jpg")];
let sample_03_hashes: [u64; 3] = [135670932300497406,
135670932300497406,
135670932300497406];
let sample_03_hashes: [u64; 3] =
[135670932300497406, 135670932300497406, 135670932300497406];
test_imageset_hash(hash::HashType::AHash,
hash::Precision::Medium,
1u64,
@ -356,9 +360,8 @@ mod tests {
let sample_03_images: [&Path; 3] = [&Path::new("./test_images/sample_03_large.jpg"),
&Path::new("./test_images/sample_03_medium.jpg"),
&Path::new("./test_images/sample_03_small.jpg")];
let sample_03_hashes: [u64; 3] = [262683193365159876,
225528496439353284,
225528496435158982];
let sample_03_hashes: [u64; 3] =
[262683193365159876, 225528496439353284, 225528496435158982];
test_imageset_hash(hash::HashType::DHash,
hash::Precision::Medium,
4u64,
@ -460,11 +463,11 @@ mod tests {
&hash::HashType::PHash);
bench.iter(|| {
// Sample_01 Bench
lib.get_perceptual_hash(&Path::new("./test_images/sample_01_large.jpg"),
&hash::Precision::Medium,
&hash::HashType::PHash);
})
// Sample_01 Bench
lib.get_perceptual_hash(&Path::new("./test_images/sample_01_large.jpg"),
&hash::Precision::Medium,
&hash::HashType::PHash);
})
}
#[cfg(feature = "bench")]
@ -474,10 +477,10 @@ mod tests {
let lib = PIHash::new(None);
bench.iter(|| {
// Sample_01 Bench
lib.get_perceptual_hash(&Path::new("./test_images/sample_01_large.jpg"),
&hash::Precision::Medium,
&hash::HashType::PHash);
})
// Sample_01 Bench
lib.get_perceptual_hash(&Path::new("./test_images/sample_01_large.jpg"),
&hash::Precision::Medium,
&hash::HashType::PHash);
})
}
}

10
src/main.rs

@ -44,8 +44,8 @@ struct Args {
fn main() {
let args: Args = Docopt::new(USAGE)
.and_then(|d| d.decode())
.unwrap_or_else(|e| e.exit());
.and_then(|d| d.decode())
.unwrap_or_else(|e| e.exit());
// Print version information and exit
if args.flag_version {
@ -63,8 +63,10 @@ fn main() {
let mut comparison_hashes: Vec<pihash::hash::PerceptualHashes> = Vec::new();
for index in 0..args.arg_comparison.len() {
comparison_hashes.push(get_requested_perceptual_hashes(&lib,
&Path::new(&args.arg_comparison[index]), &args));
comparison_hashes
.push(get_requested_perceptual_hashes(&lib,
&Path::new(&args.arg_comparison[index]),
&args));
}
let mut similar_images: Vec<&str> = Vec::new();

Loading…
Cancel
Save