You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

67 lines
2.3 KiB

9 years ago
9 years ago
9 years ago
  1. // Copyright 2016 Drew Short <drew@sothr.com>.
  2. //
  3. // Licensed under the MIT license<LICENSE-MIT or http://opensource.org/licenses/MIT>.
  4. // This file may not be copied, modified, or distributed except according to those terms.
  5. use super::{HashType, PerceptualHash, Precision, PreparedImage};
  6. use super::prepare_image;
  7. use super::image::{GenericImage, Pixel};
  8. use std::path::Path;
  9. use cache::Cache;
  10. pub struct AHash<'a> {
  11. prepared_image: Box<PreparedImage<'a>>,
  12. }
  13. impl<'a> AHash<'a> {
  14. pub fn new(path: &'a Path, precision: &Precision, cache: &Option<Cache>) -> Self {
  15. AHash {
  16. prepared_image: Box::new(prepare_image(&path, &HashType::AHash, &precision, cache)),
  17. }
  18. }
  19. }
  20. impl<'a> PerceptualHash for AHash<'a> {
  21. /**
  22. * Calculate the ahash of the provided prepared image.
  23. *
  24. * # Returns
  25. *
  26. * A u64 representing the value of the hash
  27. */
  28. fn get_hash(&self, _: &Option<Cache>) -> u64 {
  29. match self.prepared_image.image {
  30. Some(ref image) => {
  31. let (width, height) = image.dimensions();
  32. // calculating the average pixel value
  33. let mut total = 0u64;
  34. for pixel in image.pixels() {
  35. let channels = pixel.channels();
  36. // println!("Pixel is: {}", channels[0]);
  37. total += channels[0] as u64;
  38. }
  39. let mean = total / (width * height) as u64;
  40. // println!("Mean for {} is {}", prepared_image.orig_path, mean);
  41. // Calculating a hash based on the mean
  42. let mut hash = 0u64;
  43. for pixel in image.pixels() {
  44. let channels = pixel.channels();
  45. let pixel_sum = channels[0] as u64;
  46. if pixel_sum >= mean {
  47. hash |= 1;
  48. // println!("Pixel {} is >= {} therefore {:b}", pixel_sum, mean, hash);
  49. } else {
  50. hash |= 0;
  51. // println!("Pixel {} is < {} therefore {:b}", pixel_sum, mean, hash);
  52. }
  53. hash <<= 1;
  54. }
  55. // println!("Hash for {} is {}", prepared_image.orig_path, hash);
  56. hash
  57. }
  58. None => 0u64,
  59. }
  60. }
  61. }