PHP实现搜索相似图片
感知哈希算法
count<=5匹配最相似
count>10两张不同的图片
var_dump(ImageHash::run(‘./1.png',‘./psb.jpg'));
<?php
classImageHash{
constFILE_NOT_FOUND='-1';
constFILE_EXTNAME_ILLEGAL='-2';
privatefunction__construct(){}
publicstaticfunctionrun($src1,$src2){
static$self;
if(!$self)$self=newstatic;
if(!is_file($src1)||!is_file($src2))exit(self::FILE_NOT_FOUND);
$hash1=$self->getHashValue($src1);
$hash2=$self->getHashValue($src2);
if(strlen($hash1)!==strlen($hash2))returnfalse;
$count=0;
$len=strlen($hash1);
for($i=0;$i<$len;$i++)if($hash1[$i]!==$hash2[$i])$count++;
return$count<=10?true:false;
}
publicfunctiongetImage($file){
$extname=pathinfo($file,PATHINFO_EXTENSION);
if(!in_array($extname,['jpg','jpeg','png','gif']))exit(self::FILE_EXTNAME_ILLEGAL);
$img=call_user_func('imagecreatefrom'.($extname=='jpg'?'jpeg':$extname),$file);
return$img;
}
publicfunctiongetHashValue($file){
$w=8;
$h=8;
$img=imagecreatetruecolor($w,$h);
list($src_w,$src_h)=getimagesize($file);
$src=$this->getImage($file);
imagecopyresampled($img,$src,0,0,0,0,$w,$h,$src_w,$src_h);
imagedestroy($src);
$total=0;
$array=array();
for($y=0;$y<$h;$y++){
for($x=0;$x<$w;$x++){
$gray=(imagecolorat($img,$x,$y)>>8)&0xFF;
if(!isset($array[$y]))$array[$y]=array();
$array[$y][$x]=$gray;
$total+=$gray;
}
}
imagedestroy($img);
$average=intval($total/($w*$h*2));
$hash='';
for($y=0;$y<$h;$y++){
for($x=0;$x<$w;$x++){
$hash.=($array[$y][$x]>=$average)?'1':'0';
}
}
var_dump($hash);
return$hash;
}
}
var_dump(ImageHash::run('./1.png','./psb.jpg'));
方法二:
hash($f);
}
return$isString?$result[0]:$result;
}
publicfunctioncheckIsSimilarImg($imgHash,$otherImgHash){
if(file_exists($imgHash)&&file_exists($otherImgHash)){
$imgHash=$this->run($imgHash);
$otherImgHash=$this->run($otherImgHash);
}
if(strlen($imgHash)!==strlen($otherImgHash))returnfalse;
$count=0;
$len=strlen($imgHash);
for($i=0;$i<$len;$i++){
if($imgHash{$i}!==$otherImgHash{$i}){
$count++;
}
}
return$count<=(5*$rate*$rate)?true:false;
}
publicfunctionhash($file){
if(!file_exists($file)){
returnfalse;
}
$height=8*$this->rate;
$width=8*$this->rate;
$img=imagecreatetruecolor($width,$height);
list($w,$h)=getimagesize($file);
$source=$this->createImg($file);
imagecopyresampled($img,$source,0,0,0,0,$width,$height,$w,$h);
$value=$this->getHashValue($img);
imagedestroy($img);
return$value;
}
publicfunctiongetHashValue($img){
$width=imagesx($img);
$height=imagesy($img);
$total=0;
$array=array();
for($y=0;$y<$height;$y++){
for($x=0;$x<$width;$x++){
$gray=(imagecolorat($img,$x,$y)>>8)&0xFF;
if(!is_array($array[$y])){
$array[$y]=array();
}
$array[$y][$x]=$gray;
$total+=$gray;
}
}
$average=intval($total/(64*$this->rate*$this->rate));
$result='';
for($y=0;$y<$height;$y++){
for($x=0;$x<$width;$x++){
if($array[$y][$x]>=$average){
$result.='1';
}else{
$result.='0';
}
}
}
return$result;
}
publicfunctioncreateImg($file){
$ext=$this->getFileExt($file);
if($ext==='jpeg')$ext='jpg';
$img=null;
switch($ext){
case'png':$img=imagecreatefrompng($file);break;
case'jpg':$img=imagecreatefromjpeg($file);break;
case'gif':$img=imagecreatefromgif($file);
}
return$img;
}
publicfunctiongetFileExt($file){
$infos=explode('.',$file);
$ext=strtolower($infos[count($infos)-1]);
return$ext;
}
}
调用方式如下:
require_once"Imghash.class.php";
$instance=ImgHash::getInstance();
$result=$instance->checkIsSimilarImg('chenyin/IMG_3214.png','chenyin/IMG_3212.JPG');
如果$result值为true,则表明2个图片相似,否则不相似。