php-Image-PerceptualHash/lib/PerceptualHash.php

102 lines
2.2 KiB
PHP
Raw Normal View History

2015-01-09 11:28:30 +09:00
<?php
namespace Image;
use Exception;
use Image\PerceptualHash\Algorithm;
use Image\PerceptualHash\Algorithm\AverageHash;
class PerceptualHash {
/**
@var Algorithm The hasing algorithm
*/
protected $algorithm;
/**
* @var string Calculated binary hash
*/
protected $bin;
/**
* @var string Calculated hex hash
*/
protected $hex;
/**
* @param mixed $file
* @param Algorithm $algorithm
*/
2015-01-09 11:28:30 +09:00
public function __construct($file, Algorithm $algorithm = null)
{
$resource = is_resource($file) ? $file : $this->load($file);
2015-01-09 11:28:30 +09:00
$this->algorithm = $algorithm ?: new AverageHash;
$this->bin = $this->algorithm->bin($resource);
$this->hex = $this->algorithm->hex($this->bin);
2015-01-09 11:28:30 +09:00
}
public function bin()
2015-01-09 11:28:30 +09:00
{
return $this->bin;
2015-01-09 11:28:30 +09:00
}
public function hex()
{
return $this->hex;
}
/**
* @param mixed $file
* @return integer The distance to $file
*/
2015-01-09 11:28:30 +09:00
public function compare($file)
{
$algorithm_class = get_class($this->algorithm);
$objective = new self($file, new $algorithm_class);
return self::distance($this->bin, $objective->bin);
2015-01-09 11:28:30 +09:00
}
/**
* Calculate the Hamming distance between two hashes
*
* @param string $hash1
* @param string $hash2
* @return integer $diff
* @throws
*/
public static function distance($hash1, $hash2)
2015-01-09 11:28:30 +09:00
{
if (!is_string($hash1) || !is_string($hash2)) {
throw new Exception();
}
if (strlen($hash1) !== strlen($hash2)) {
throw new Exception();
}
$diff = 0;
$split_hash1 = str_split($hash1);
$split_hash2 = str_split($hash2);
for ($i = 0; $i < count($split_hash1); $i++) {
if ($split_hash1[$i] !== $split_hash2[$i]) {
$diff++;
}
}
return (int)$diff;
2015-01-09 11:28:30 +09:00
}
protected function load($file)
{
if (!file_exists($file)) {
throw new Exception("No such a file $file");
}
try {
return imagecreatefromstring(file_get_contents($file));
} catch (Exception $e) {
throw $e;
}
}
}