diff --git a/src/main/scala/com/sothr/imagetools/hash/AHash.scala b/src/main/scala/com/sothr/imagetools/hash/AHash.scala index 0b7a32e..cfec911 100644 --- a/src/main/scala/com/sothr/imagetools/hash/AHash.scala +++ b/src/main/scala/com/sothr/imagetools/hash/AHash.scala @@ -1,10 +1,48 @@ package com.sothr.imagetools.hash +import grizzled.slf4j.Logging + /** * Created by dev on 1/22/14. */ -object AHash extends PerceptualHasher { +object AHash extends PerceptualHasher with Logging { def getHash(imageData: Array[Array[Int]]): Long = { - return 0L + debug("Generating AHash") + val width = imageData.length + val height = imageData(0).length + debug(s"Image data size: ${width}x${height}") + + //calculate average pixel + var total = 0 + for (row <- 0 until height) { + for (col <- 0 until width) { + total += imageData(row)(col) + } + } + val mean = total / (height * width) + + //calculate ahash + var hash = 0L + for (row <- 0 until height by 2) { + //process each column + for (col <- 0 until width by 1) { + hash <<= 1 + val pixel = imageData(row)(col) + //If the current pixel is at or above the mean, store it as a one, else store it as a zero + if (pixel >= mean) hash |= 1 else hash |= 0 + } + + if ((row +1) < width) { + val nextRow = row + 1 + //process each column + for (col <- (width - 1) to 0 by -1) { + hash <<= 1 + val pixel = imageData(nextRow)(col) + if (pixel >= mean) hash |= 1 else hash |= 0 + } + } + } + debug(s"Computed AHash: $hash from ${width * height} pixels") + hash } } diff --git a/src/main/scala/com/sothr/imagetools/hash/DHash.scala b/src/main/scala/com/sothr/imagetools/hash/DHash.scala index 7d8e652..e1d1c77 100644 --- a/src/main/scala/com/sothr/imagetools/hash/DHash.scala +++ b/src/main/scala/com/sothr/imagetools/hash/DHash.scala @@ -13,7 +13,7 @@ object DHash extends PerceptualHasher with Logging { debug(s"Image data size: ${width}x${height}") //calculate dhash - var hash = 0 + var hash = 0L var previousPixel = imageData(height-1)(width-1) var previousLocation = (height-1, width-1) if (height % 2 == 0) { @@ -27,10 +27,10 @@ object DHash extends PerceptualHasher with Logging { hash <<= 1 val pixel = imageData(row)(col) //debug(s"previousPixel: $previousPixel currentPixel: $pixel previousLocation: $previousLocation currentLocation: (${row},${col})") - //binary or the current bit based on whether the value + //binary of the current bit based on whether the value //of the current pixel is greater or equal to the previous pixel if (pixel >= previousPixel) hash |= 1 else hash |= 0 - //debug(s"hash: $hash") + //debug(s"(${row},${col})=$pixel hash=${hash.toBinaryString}") previousPixel = pixel previousLocation = (row, col) } @@ -42,16 +42,14 @@ object DHash extends PerceptualHasher with Logging { hash <<= 1 val pixel = imageData(nextRow)(col) //debug(s"previousPixel: $previousPixel currentPixel: $pixel previousLocation: $previousLocation currentLocation: (${nextRow},${col})") - //binary or the current bit based on whether the value - //of the current pixel is greater or equal to the previous pixel if (pixel >= previousPixel) hash |= 1 else hash |= 0 - //debug(s"hash: $hash") + //debug(s"(${row},${col})=$pixel hash=${hash.toBinaryString}") previousPixel = pixel previousLocation = (nextRow, col) } } } - debug(s"Computed Hash: $hash from ${width * height} pixels") + debug(s"Computed DHash: $hash from ${width * height} pixels") hash } } diff --git a/src/test/scala/com/sothr/imagetools/hash/HashServiceTest.scala b/src/test/scala/com/sothr/imagetools/hash/HashServiceTest.scala index 274b728..5581ac5 100644 --- a/src/test/scala/com/sothr/imagetools/hash/HashServiceTest.scala +++ b/src/test/scala/com/sothr/imagetools/hash/HashServiceTest.scala @@ -44,6 +44,21 @@ class HashServiceTest extends BaseTest { assert(true) } + test("Confirm Largest DHash Output ") { + val testData:Array[Array[Int]] = Array( + Array(1,2,3,4,5,6,7,8), + Array(16,15,14,13,12,11,10,9), + Array(17,18,19,20,21,22,23,24), + Array(32,31,30,29,28,27,26,25), + Array(33,34,35,36,37,38,39,40), + Array(48,47,46,45,44,43,42,41), + Array(49,50,51,52,53,54,55,56), + Array(64,63,62,61,60,59,58,57)) + val hash = DHash.getHash(testData) + debug(s"Hash of test array: $hash") + assert(hash == (Long.MaxValue)) + } + test("Calculate DHash Large Sample Image 1") { debug("Starting 'Calculate DHash Large Sample Image 1' test") val sample = new File(TestParams.LargeSampleImage1) @@ -51,8 +66,8 @@ class HashServiceTest extends BaseTest { val image = ImageIO.read(sample) debug(s"Image: width: ${image.getWidth} height: ${image.getHeight}") val hash = HashService.getDhash(image) - debug(s"Testing that $hash = -1689609389L") - assert(hash == -1689609389L) + debug(s"Testing that $hash = 4004374827879799635L") + assert(hash == 4004374827879799635L) } test("Calculate DHash Medium Sample Image 1") { @@ -62,8 +77,8 @@ class HashServiceTest extends BaseTest { val image = ImageIO.read(sample) debug(s"Image: width: ${image.getWidth} height: ${image.getHeight}") val hash = HashService.getDhash(image) - debug(s"Testing that $hash = -1689609389L") - assert(hash == -1689609389L) + debug(s"Testing that $hash = 4004374827879799635L") + assert(hash == 4004374827879799635L) } test("Calculate DHash Small Sample Image 1") { @@ -73,8 +88,8 @@ class HashServiceTest extends BaseTest { val image = ImageIO.read(sample) debug(s"Image: width: ${image.getWidth} height: ${image.getHeight}") val hash = HashService.getDhash(image) - debug(s"Testing that $hash = -1689609389L") - assert(hash == -1689609389L) + debug(s"Testing that $hash = 4004383623972821843L") + assert(hash == 4004383623972821843L) } test("DHash Of Large, Medium, And Small Sample 1 Must Be Similar") {