Browse Source

Addition work and testing... Pretty sure there's some endianness weirdness still going on, have to test on x86 to confirm.

develop
Drew Short 9 years ago
parent
commit
ba86192900
  1. 23
      src/hash.rs
  2. 69
      src/lib.rs

23
src/hash.rs

@ -9,18 +9,22 @@ extern crate image;
use std::path::Path; use std::path::Path;
use self::image::{ use self::image::{
GenericImage, GenericImage,
Pixel
Pixel,
FilterType
}; };
use self::image::imageops;
pub struct PreparedImage<'a> { pub struct PreparedImage<'a> {
orig_path: &'a str, orig_path: &'a str,
grey_image: image::ImageBuffer<image::Luma<u8>,Vec<u8>>
image: image::ImageBuffer<image::Luma<u8>,Vec<u8>>
} }
pub fn prepare_image(path: &Path) -> PreparedImage {
let grey_img = image::open(path).unwrap().to_luma();
pub fn prepare_image(path: &Path, size: u32) -> PreparedImage {
let image_path = path.to_str().unwrap(); let image_path = path.to_str().unwrap();
PreparedImage { orig_path: &*image_path, grey_image: grey_img }
let image = image::open(path).unwrap();
let small_image = image.resize_exact(size, size, image::FilterType::Lanczos3);
let grey_image = small_image.to_luma();
PreparedImage { orig_path: &*image_path, image: grey_image }
} }
/* /*
@ -52,29 +56,34 @@ pub fn calculate_hamming_distance(hash1: u64, hash2: u64) -> u64 {
* Returns a u64 representing the value of the hash * Returns a u64 representing the value of the hash
*/ */
pub fn get_ahash(prepared_image: PreparedImage) -> u64 { pub fn get_ahash(prepared_image: PreparedImage) -> u64 {
let img = prepared_image.grey_image;
let img = prepared_image.image;
let (width, height) = img.dimensions(); let (width, height) = img.dimensions();
// calculating the average pixel value // calculating the average pixel value
let mut total = 0u64; let mut total = 0u64;
for pixel in img.pixels() { for pixel in img.pixels() {
let channels = pixel.channels(); let channels = pixel.channels();
//println!("Pixel is: {}", channels[0]);
total += channels[0] as u64; total += channels[0] as u64;
} }
let mean = total / (width*height) as u64; let mean = total / (width*height) as u64;
//println!("Mean for {} is {}", prepared_image.orig_path, mean);
// Calculating a hash based on the mean // Calculating a hash based on the mean
let mut hash = 0u64; let mut hash = 0u64;
for pixel in img.pixels() { for pixel in img.pixels() {
let channels = pixel.channels(); let channels = pixel.channels();
let pixel_sum = channels[0] as u64; let pixel_sum = channels[0] as u64;
hash <<= 1;
if pixel_sum >= mean { if pixel_sum >= mean {
hash |= 1; hash |= 1;
//println!("Pixel {} is >= {} therefore {:b}", pixel_sum, mean, hash);
} else { } else {
hash |= 0; hash |= 0;
//println!("Pixel {} is < {} therefore {:b}", pixel_sum, mean, hash);
} }
hash <<= 1;
} }
//println!("Hash for {} is {}", prepared_image.orig_path, hash);
return hash; return hash;
} }

69
src/lib.rs

@ -7,8 +7,21 @@
mod hash; mod hash;
pub fn hello(mut result: String) -> String { pub fn hello(mut result: String) -> String {
let helloworld = "Hello, World!";
let helloworld = "Hello, World!\n";
result.push_str(helloworld); result.push_str(helloworld);
let n = 1u8;
let ns = format!("1: {:b}\n", n);
let n2 = 2u8;
let n2s = format!("2: {:b}\n", n2);
result.push_str(&ns);
result.push_str(&n2s);
let mut endian = "Big Endian\n";
if cfg!(target_endian = "big") {
result.push_str(endian);
} else {
endian = "Little Endian\n";
result.push_str(endian);
}
result result
} }
@ -61,9 +74,9 @@ mod tests {
expected_large_small_hamming: u64, expected_large_small_hamming: u64,
expected_medium_small_hamming: u64) { expected_medium_small_hamming: u64) {
let large_prepared_image = hash::prepare_image(path::Path::new(large_path));
let medium_prepared_image = hash::prepare_image(path::Path::new(medium_path));
let small_prepared_image = hash::prepare_image(path::Path::new(small_path));
let large_prepared_image = hash::prepare_image(path::Path::new(large_path), 8u32);
let medium_prepared_image = hash::prepare_image(path::Path::new(medium_path), 8u32);
let small_prepared_image = hash::prepare_image(path::Path::new(small_path), 8u32);
let large_ahash = hash::get_ahash(large_prepared_image); let large_ahash = hash::get_ahash(large_prepared_image);
let medium_ahash = hash::get_ahash(medium_prepared_image); let medium_ahash = hash::get_ahash(medium_prepared_image);
@ -98,12 +111,50 @@ mod tests {
"./test_images/sample_01_large.jpg", "./test_images/sample_01_large.jpg",
"./test_images/sample_01_medium.jpg", "./test_images/sample_01_medium.jpg",
"./test_images/sample_01_small.jpg", "./test_images/sample_01_small.jpg",
18446744073709551615u64,
18446744073709551615u64,
9223372036854775807u64,
857051991849750,
857051991849750,
857051991849750,
0u64,
0u64,
0u64
);
// Sample_02 tests
test_image_set_ahash(
"./test_images/sample_02_large.jpg",
"./test_images/sample_02_medium.jpg",
"./test_images/sample_02_small.jpg",
18446744073441116160,
18446744073441116160,
18446744073441116160,
0u64,
0u64,
0u64
);
// Sample_03 tests
test_image_set_ahash(
"./test_images/sample_03_large.jpg",
"./test_images/sample_03_medium.jpg",
"./test_images/sample_03_small.jpg",
135670932300497406,
135670932300497406,
135670932300497406,
0u64,
0u64,
0u64
);
// Sample_04 tests
test_image_set_ahash(
"./test_images/sample_04_large.jpg",
"./test_images/sample_04_medium.jpg",
"./test_images/sample_04_small.jpg",
18446460933225054208,
18446460933225054208,
18446460933225054208,
0u64,
0u64, 0u64,
1u64,
1u64
0u64
); );
} }

Loading…
Cancel
Save