public function hash($image, $editor)
{
$width = 9;
$height = 8;
$image = clone $image;
// Make sure we are working on the clone if Image is passed
$editor->resizeExact($image, $width, $height);
// Resize to exactly 9x8
$imagick = $image->getCore();
// Build hash
$hash = '';
for ($y = 0; $y < $height; $y++) {
// Get the pixel value for the leftmost pixel.
$rgba = $imagick->getImagePixelColor(0, $y)->getColor();
$left = floor(($rgba['r'] + $rgba['g'] + $rgba['b']) / 3);
for ($x = 1; $x < $width; $x++) {
// Get the pixel value for each pixel starting from position 1.
$rgba = $imagick->getImagePixelColor($x, $y)->getColor();
$right = floor(($rgba['r'] + $rgba['g'] + $rgba['b']) / 3);
// Each hash bit is set based on whether the left pixel is brighter than the right pixel.
if ($left > $right) {
$hash .= '1';
} else {
$hash .= '0';
}
// Prepare the next loop.
$left = $right;
}
}
$editor->free($image);
return $hash;
}
/** * Compare two images and returns a hamming distance. A value of 0 indicates a likely similar picture. A value between 1 and 10 is potentially a variation. A value greater than 10 is likely a different image. * * @param ImageInterface|string $image1 * @param ImageInterface|string $image2 * * @return int Hamming distance. Note: This breaks the chain if you are doing fluent api calls as it does not return an Editor. * @throws \Exception */ public function compare($image1, $image2) { if (is_string($image1)) { // If string passed, turn it into a Image object $image1 = Image::createFromFile($image1); $this->flatten($image1); } if (is_string($image2)) { // If string passed, turn it into a Image object $image2 = Image::createFromFile($image2); $this->flatten($image2); } $hash = new DifferenceHash(); $bin1 = $hash->hash($image1, $this); $bin2 = $hash->hash($image2, $this); $str1 = str_split($bin1); $str2 = str_split($bin2); $distance = 0; foreach ($str1 as $i => $char) { if ($char !== $str2[$i]) { $distance++; } } return $distance; }