forked from jenssegers/imagehash
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
✨ Big rework including working BlockHash, better hash generation
- Loading branch information
1 parent
c499721
commit 006a1bc
Showing
13 changed files
with
411 additions
and
391 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,122 @@ | ||
<?php | ||
|
||
namespace Jenssegers\ImageHash; | ||
|
||
use JsonSerializable; | ||
use phpseclib\Math\BigInteger; | ||
|
||
class Hash implements JsonSerializable | ||
{ | ||
/** | ||
* @var BigInteger | ||
*/ | ||
protected $value; | ||
|
||
/** | ||
* @param BigInteger $value | ||
*/ | ||
private function __construct(BigInteger $value) | ||
{ | ||
$this->value = $value; | ||
} | ||
|
||
/** | ||
* @param string $hex | ||
* @return self | ||
*/ | ||
public static function fromHex($hex) | ||
{ | ||
return new self(new BigInteger($hex, 16)); | ||
} | ||
|
||
/** | ||
* @param string|array $bits | ||
* @return self | ||
*/ | ||
public static function fromBits($bits) | ||
{ | ||
if (is_array($bits)) { | ||
$bits = implode('', $bits); | ||
} | ||
|
||
return new self(new BigInteger($bits, 2)); | ||
} | ||
|
||
/** | ||
* @return string | ||
*/ | ||
public function toHex() | ||
{ | ||
return $this->value->toHex(); | ||
} | ||
|
||
/** | ||
* @return string | ||
*/ | ||
public function toBytes() | ||
{ | ||
return $this->value->toBytes(); | ||
} | ||
|
||
/** | ||
* @return string | ||
*/ | ||
public function toBits() | ||
{ | ||
return $this->value->toBits(); | ||
} | ||
|
||
/** | ||
* @return int | ||
*/ | ||
public function toInt() | ||
{ | ||
return hexdec($this->toHex()); | ||
} | ||
|
||
/** | ||
* @param Hash $hash | ||
* @return int | ||
*/ | ||
public function distance(Hash $hash) | ||
{ | ||
if (extension_loaded('gmp')) { | ||
return gmp_hamdist('0x' . $this->toHex(), '0x' . $hash->toHex()); | ||
} | ||
|
||
$bits1 = $this->toBits(); | ||
$bits2 = $hash->toBits(); | ||
$length = max(strlen($bits1), strlen($bits2)); | ||
|
||
// Add leading zeros so the bit strings are the same length. | ||
$bits1 = str_pad($bits1, $length, '0', STR_PAD_LEFT); | ||
$bits2 = str_pad($bits2, $length, '0', STR_PAD_LEFT); | ||
|
||
return count(array_diff_assoc(str_split($bits1), str_split($bits2))); | ||
} | ||
|
||
/** | ||
* @param Hash $hash | ||
* @return bool | ||
*/ | ||
public function equals(Hash $hash) | ||
{ | ||
return $this->toHex() === $hash->toHex(); | ||
} | ||
|
||
/** | ||
* @return string | ||
*/ | ||
public function __toString() | ||
{ | ||
return $this->toHex(); | ||
} | ||
|
||
/** | ||
* @inheritdoc | ||
*/ | ||
public function jsonSerialize() | ||
{ | ||
return (string) $this; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,45 +1,49 @@ | ||
<?php namespace Jenssegers\ImageHash\Implementations; | ||
|
||
use Intervention\Image\Image; | ||
use Jenssegers\ImageHash\Hash; | ||
use Jenssegers\ImageHash\Implementation; | ||
|
||
class AverageHash implements Implementation | ||
{ | ||
/** | ||
* Downscaled image size. | ||
* @var int | ||
*/ | ||
const SIZE = 8; | ||
protected $size; | ||
|
||
/** | ||
* @param int $size | ||
*/ | ||
public function __construct($size = 8) | ||
{ | ||
$this->size = $size; | ||
} | ||
|
||
/** | ||
* @inheritdoc | ||
*/ | ||
public function hash(Image $image) | ||
{ | ||
// Resize the image. | ||
$resized = $image->resize(static::SIZE, static::SIZE); | ||
$resized = $image->resize($this->size, $this->size); | ||
|
||
// Create an array of greyscale pixel values. | ||
$pixels = []; | ||
for ($y = 0; $y < static::SIZE; $y++) { | ||
for ($x = 0; $x < static::SIZE; $x++) { | ||
for ($y = 0; $y < $this->size; $y++) { | ||
for ($x = 0; $x < $this->size; $x++) { | ||
$rgb = $resized->pickColor($x, $y); | ||
$pixels[] = floor(($rgb[0] + $rgb[1] + $rgb[2]) / 3); | ||
$pixels[] = (int) floor(($rgb[0] * 0.299) + ($rgb[1] * 0.587) + ($rgb[2] * 0.114)); | ||
} | ||
} | ||
|
||
// Get the average pixel value. | ||
$average = floor(array_sum($pixels) / count($pixels)); | ||
|
||
// Each hash bit is set based on whether the current pixels value is above or below the average. | ||
$hash = 0; | ||
$one = 1; | ||
foreach ($pixels as $pixel) { | ||
if ($pixel > $average) { | ||
$hash |= $one; | ||
} | ||
$one = $one << 1; | ||
} | ||
$bits = array_map(function ($pixel) use ($average) { | ||
return (int) ($pixel > $average); | ||
}, $pixels); | ||
|
||
return $hash; | ||
return Hash::fromBits($bits); | ||
} | ||
} |
Oops, something went wrong.