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个图片相似,否则不相似。