Skip to content

Instantly share code, notes, and snippets.

@jellyninjadev
Created December 14, 2015 16:04
Show Gist options
  • Save jellyninjadev/05d0293a89481cf9f9c2 to your computer and use it in GitHub Desktop.
Save jellyninjadev/05d0293a89481cf9f9c2 to your computer and use it in GitHub Desktop.
<?php
/* ImageDiff --------------------------------------------
Class to identify difference between two images.
Difference is identified in comparing the delta between average color.
Based on idea from:
http://www.hackerfactor.com/blog/?/archives/432-Looks-Like-It.html
call function Diff to get an Array with the results
Diff Description:
Array Diff( string $im1, string $im2 [, boolean $save[, integer $size]] ):
$im1: Path to first file
$im2: Path to second file
$save: Saves the compare images in the same folder than the soruce file1
details are returned back in the array.
$size: defines the resize image size which is used to compare.
default is 16 pixels, Higher = more Detail, but slower
Example:
$clIM = new ImageDiff;
$ret = clIM->Diff("./images/image1.jpg","./images/image2.jpg", true)
print_r($ret);
*/
class ImageDiff {
public $dbg = false;
public function Diff($im1, $im2, $save = false, $size = 16) {
// $im1, $im2 = path to two images
// $size default 8, resize size for delta processing
// $save default. saves the resized images (), same target as src with prefix sized_
$dbg = $this->dbg;
// Vergleichsbilder erzeugen Nr. 1
$i1 = imagecreatefromjpeg($im1);
list($width1, $height1) = getimagesize($im1);
$id1 = imagecreatetruecolor($size, $size);
imagecopyresized($id1, $i1, 0, 0, 0, 0, $size, $size, $width1, $height1);
imagefilter($id1, IMG_FILTER_GRAYSCALE);
// Vergleichsbilder erzeugen Nr. 2
$i2 = imagecreatefromjpeg($im2);
list($width2, $height2) = getimagesize($im2);
$id2 = imagecreatetruecolor($size, $size);
imagecopyresized($id2, $i2, 0, 0, 0, 0, $size, $size, $width2, $height2);
imagefilter($id2, IMG_FILTER_GRAYSCALE);
// Nun Pixel
$i1_avg = $this->average($id1);
$i2_avg = $this->average($id2);
//Compute Hash
$i1_hash = $this->ComputeHash($id1, $i1_avg);
if ($dbg) echo "Hash Bild 1 : " . implode($i1_hash) . " <br>";
$i2_hash = $this->ComputeHash($id2, $i2_avg);
if ($dbg) echo "Hash Bild 2 : " . implode($i2_hash) . " <br>";
// Count Distance:
$fail = 0;
for ($x = 0; $x < count($i2_hash); $x++) {
if ($i2_hash[$x] != $i1_hash[$x]) {
$fail++;
}
}
$delta = ($fail / ($size * $size)) * 100;
if ($save) {
// Create Delta image
$id3 = imagecreatetruecolor($size, $size);
imagecopy($id3, $id1, 0, 0, 0, 0, $size, $size);
$col = imagecolorallocate($id3, 0, 255, 0);
$x = $y = 0;
$cnt = 0;
for ($y = 0; $y < $size; $y++) {
for ($x = 0; $x < $size; $x++) {
if ($i2_hash[$cnt] != $i1_hash[$cnt]) {
imagesetpixel($id3, $x, $y, $col);
}
$cnt++;
}
}
$fndelta = pathinfo($im1, PATHINFO_DIRNAME) . "/delta_" . basename($im1);
imagejpeg($id3, $fndelta);
$ret["deltaimage"] = $fndelta;
// Save temporary images
$fn1 = pathinfo($im1, PATHINFO_DIRNAME) . "/sized_" . basename($im1);
$fn2 = pathinfo($im2, PATHINFO_DIRNAME) . "/sized_" . basename($im2);
imagejpeg($id1, $fn1);
imagejpeg($id2, $fn2);
$ret["tempimg1"] = $fn1;
$ret["tempimg2"] = $fn2;
}
$ret["delta"] = $delta;
return $ret;
}
private function average($img) {
$w = imagesx($img);
$h = imagesy($img);
$r = $g = $b = 0;
for ($y = 0; $y < $h; $y++) {
for ($x = 0; $x < $w; $x++) {
$rgb = imagecolorat($img, $x, $y);
$r += $rgb >> 16;
//$g += $rgb >> 8 & 255;
//$b += $rgb & 255;
}
}
$pxls = $w * $h;
//$r = (round($r / $pxls));
//$g = (round($g / $pxls));
$r = (round($r / $pxls)); // Da wir graustufen verwenden reicht eine Farbe
//return $r ."," . $g .",". $b;
if ($r < 10) $r = 0; // Wenn fast Schwarz, dann schwarz!
if ($r > 245) $r = 255; // auch mit Weiß so verfahren.
return $r;
}
private function ComputeHash($img, $avg = 100) {
global $dbg;
$w = imagesx($img);
$h = imagesy($img);
$r = $g = $b = 0;
for ($y = 0; $y < $h; $y++) {
for ($x = 0; $x < $w; $x++) {
$rgb = imagecolorat($img, $x, $y);
$r = $rgb >> 16;
if ($r <= $avg) {
$hash [] = "1";
} else {
$hash [] = "0";
}
}
}
return $hash;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment