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.

73 lines
2.2 KiB

8 years ago
8 years ago
8 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. extern crate image;
  6. use std::path::Path;
  7. use cache::Cache;
  8. use super::{HashType, PerceptualHash, Precision, PreparedImage};
  9. use super::prepare_image;
  10. use self::image::{GenericImage, GenericImageView};
  11. pub struct DHash<'a> {
  12. prepared_image: Box<PreparedImage<'a>>,
  13. }
  14. impl<'a> DHash<'a> {
  15. pub fn new(path: &'a Path, precision: &Precision, cache: &Option<Cache>) -> Self {
  16. DHash {
  17. prepared_image: Box::new(prepare_image(&path, &HashType::DHash, &precision, cache)),
  18. }
  19. }
  20. }
  21. impl<'a> PerceptualHash for DHash<'a> {
  22. /**
  23. * Calculate the dhash of the provided prepared image
  24. *
  25. * # Return
  26. *
  27. * Returns a u64 representing the value of the hash
  28. */
  29. fn get_hash(&self, _: &Option<Cache>) -> u64 {
  30. match self.prepared_image.image {
  31. Some(ref image) => {
  32. let (_, _, first_pixel) = image.pixels().nth(0).unwrap();
  33. let (_, _, last_pixel) = image.pixels().last().unwrap();
  34. let first_pixel_value = first_pixel.0[0] as u64;
  35. let last_pixel_value = last_pixel.0[0] as u64;
  36. // Calculate the dhash
  37. let mut previous_pixel_value = 0u64;
  38. let mut hash = 0u64;
  39. for (x, y, pixel) in image.pixels() {
  40. if x == 0 && y == 0 {
  41. previous_pixel_value = pixel.0[0] as u64;
  42. continue;
  43. }
  44. let pixel_val = pixel.0[0] as u64;
  45. if pixel_val >= previous_pixel_value {
  46. hash |= 1;
  47. } else {
  48. hash |= 0;
  49. }
  50. hash <<= 1;
  51. previous_pixel_value = first_pixel_value;
  52. }
  53. if first_pixel_value >= last_pixel_value {
  54. hash |= 1;
  55. } else {
  56. hash |= 0;
  57. }
  58. hash
  59. }
  60. None => 0u64,
  61. }
  62. }
  63. }