Skip to content

Instantly share code, notes, and snippets.

@garygreen
Created May 28, 2020 13:00
Show Gist options
  • Save garygreen/dbb565fa1efbf5b8179d4570e88adb25 to your computer and use it in GitHub Desktop.
Save garygreen/dbb565fa1efbf5b8179d4570e88adb25 to your computer and use it in GitHub Desktop.
GD Difference Hash for jenssegers / imagehash package (around 4x quicker than Intervention)
<?php
namespace App\Image;
use Jenssegers\ImageHash\Hash;
use Jenssegers\ImageHash\Implementation;
class GdDifferenceHash implements Implementation
{
/**
* @var int
*/
protected $size;
/**
* @param int $size
*/
public function __construct($size = 8)
{
$this->size = $size;
}
/**
* @inheritdoc
*/
public function hash($image)
{
$source = imagecreatefromjpeg($image);
// For this implementation we create a 8x9 image.
$width = $this->size + 1;
$height = $this->size;
// Resize the image.
// $resized = $image->resize($width, $height);
$resized = imagecreatetruecolor($width, $height);
list($origwidth, $origheight) = getimagesize($image);
imagecopyresized($resized, $source, 0, 0, 0, 0, $width, $height, $origwidth, $origheight);
$bits = [];
for ($y = 0; $y < $height; $y++) {
// Get the pixel value for the leftmost pixel.
$rgb = $this->pickColor($resized, 0, $y);
$left = (int) floor(($rgb[0] * 0.299) + ($rgb[1] * 0.587) + ($rgb[2] * 0.114));
for ($x = 1; $x < $width; $x++) {
// Get the pixel value for each pixel starting from position 1.
$rgb = $this->pickColor($resized, $x, $y);
$right = (int) floor(($rgb[0] * 0.299) + ($rgb[1] * 0.587) + ($rgb[2] * 0.114));
// Each hash bit is set based on whether the left pixel is brighter than the right pixel.
// http://www.hackerfactor.com/blog/index.php?/archives/529-Kind-of-Like-That.html
$bits[] = (int) ($left > $right);
// Prepare the next loop.
$left = $right;
}
}
return Hash::fromBits($bits);
}
protected function pickColor($image, $x, $y)
{
$colorIndex = imagecolorsforindex($image, imagecolorat($image, $x, $y));
return [$colorIndex['red'], $colorIndex['green'], $colorIndex['blue']];
}
}
@garygreen
Copy link
Author

garygreen commented May 28, 2020

Disclaimer: I haven't thouroughly tested it, so you may want to double check its coming back with the same values as the current implementation.

Note: the package currently requires Imagick due to the interface, so in itself the above code won't be "plug and play" - will likely need to fork the package and adjust the interface to remove that typehint.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment