Skip to content

Instantly share code, notes, and snippets.

@Scarjit
Created August 17, 2019 15:11
Show Gist options
  • Save Scarjit/ed9cbbb291d724eca9112118c5f992ca to your computer and use it in GitHub Desktop.
Save Scarjit/ed9cbbb291d724eca9112118c5f992ca to your computer and use it in GitHub Desktop.
DHash php
<?php //Author: Tom64b | Website: github.com/Tom64b | Code based on article by Dr. Neal Krawetz | License: MIT | Date: 2017-05-12
function dhash($fname, $onlyJPG = true)
{
// load exif thumbnail if possible; otherwise- load the image
$thumb = exif_thumbnail($fname, $wid, $hei);
if (!$thumb) {
$src = ($onlyJPG) ? imagecreatefromjpeg($fname) : imagecreatefromstring(file_get_contents($fname));
list($wid, $hei) = array(imagesx($src), imagesy($src));
} else {
$src = imagecreatefromstring($thumb);
unset($thumb);
}
// resize to 9x8 = 72 pixels, apply grayscale
$img = imagecreatetruecolor(9, 8);
imagecopyresampled($img, $src, 0, 0, 0, 0, 9, 8, $wid, $hei);
imagedestroy($src);
imagefilter($img, IMG_FILTER_GRAYSCALE);
//calculate dHash (hackerfactor.com/blog/?/archives/529-Kind-of-Like-That.html)
$hash = 0;
$bit = 1;
for ($y=0; $y<8; $y++) {
if ($y == 4) { //second half of the image, this whole IF can be removed on 64bit machines
$res = sprintf("%08x", $hash);
$hash = 0;
$bit = 1;
}
$previous = imagecolorat($img, 0, $y) & 0xFF;
for ($x=1; $x<9; $x++) {
$current = imagecolorat($img, $x, $y) & 0xFF;
if ($previous > $current) {
$hash |= $bit;
}
$bit = $bit << 1;
$previous = $current;
}
}
imagedestroy($img);
return sprintf("%08x", $hash) . $res; //if you removed the IF above- remove " . $res"
}
function dhash_distance($hash1, $hash2)
{
$counts = array(0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4);
$res = 0;
for ($i=0; $i<16; $i++) {
if ($hash1[$i] != $hash2[$i]) {
$res += $counts[hexdec($hash1[$i]) ^ hexdec($hash2[$i])];
}
}
return $res;
}
<?php
ini_set('memory_limit', '-1');
include 'dhash.php';
$hashes = array();
$files = glob('_likes/*.{jpg,png,jpeg}', GLOB_BRACE);
foreach($files as $file) {
$hash = dhash($file, false);
print_r($file . " => " . $hash . "\r\n");
$hashes[$file] = $hash;
}
$dst_matrix = array();
foreach($hashes as $path1 => $hash1) {
foreach($hashes as $path2 => $hash2) {
if ($path1 != $path2) {
$dst = dhash_distance($hash1, $hash2);
if ($dst < 10) {
print_r($path1 . " || " . $path2 . " -> " . $dst ."\r\n");
if(!array_key_exists($dst,$dst_matrix)){
$dst_matrix[$dst] = array();
}
array_push($dst_matrix[$dst], [$path1, $path2]);
}
}
}
}
ksort($dst_matrix);
file_put_contents("j.json", json_encode($dst_matrix, JSON_PRETTY_PRINT));
?>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment