PHP实现的简易版图片相似度比较
由于相似图片搜索的php实现的API不怎么符合我的用途,所以我重新定义API的架构,改写成比较简单的函数方式,虽然还是用对象的方式包装。
<?php /** *图片相似度比较 * *@version $Id:ImageHash.php44292012-04-1713:20:31Zjax$ *@author jax.hu * *<code> * //Sample_1 * $aHash=ImageHash::hashImageFile('wsz.11.jpg'); * $bHash=ImageHash::hashImageFile('wsz.12.jpg'); * var_dump(ImageHash::isHashSimilar($aHash,$bHash)); * * //Sample_2 * var_dump(ImageHash::isImageFileSimilar('wsz.11.jpg','wsz.12.jpg')); *</code> */ classImageHash{ /**取样倍率1~10 *@accesspublic *@staticvarint **/ publicstatic$rate=2; /**相似度允许值0~64 *@accesspublic *@staticvarint **/ publicstatic$similarity=80; /**图片类型对应的开启函数 *@accessprivate *@staticvarstring **/ privatestatic$_createFunc=array( IMAGETYPE_GIF =>'imageCreateFromGIF', IMAGETYPE_JPEG =>'imageCreateFromJPEG', IMAGETYPE_PNG =>'imageCreateFromPNG', IMAGETYPE_BMP =>'imageCreateFromBMP', IMAGETYPE_WBMP =>'imageCreateFromWBMP', IMAGETYPE_XBM =>'imageCreateFromXBM', ); /**从文件建立图片 *@paramstring$filePath文件地址路径 *@returnresource当成功开启图片则传递图片resourceID,失败则是false **/ publicstaticfunctioncreateImage($filePath){ if(!file_exists($filePath)){returnfalse;} /*判断文件类型是否可以开启*/ $type=exif_imagetype($filePath); if(!array_key_exists($type,self::$_createFunc)){returnfalse;} $func=self::$_createFunc[$type]; if(!function_exists($func)){returnfalse;} return$func($filePath); } /**hash图片 *@paramresource$src图片resourceID *@returnstring图片hash值,失败则是false **/ publicstaticfunctionhashImage($src){ if(!$src){returnfalse;} /*缩小图片尺寸*/ $delta=8*self::$rate; $img=imageCreateTrueColor($delta,$delta); imageCopyResized($img,$src,0,0,0,0,$delta,$delta,imagesX($src),imagesY($src)); /*计算图片灰阶值*/ $grayArray=array(); for($y=0;$y<$delta;$y++){ for($x=0;$x<$delta;$x++){ $rgb=imagecolorat($img,$x,$y); $col=imagecolorsforindex($img,$rgb); $gray=intval(($col['red']+$col['green']+$col['blue'])/3)&0xFF; $grayArray[]=$gray; } } imagedestroy($img); /*计算所有像素的灰阶平均值*/ $average=array_sum($grayArray)/count($grayArray); /*计算hash值*/ $hashStr=''; foreach($grayArrayas$gray){ $hashStr.=($gray>=$average)?'1':'0'; } return$hashStr; } /**hash图片文件 *@paramstring$filePath文件地址路径 *@returnstring图片hash值,失败则是false **/ publicstaticfunctionhashImageFile($filePath){ $src=self::createImage($filePath); $hashStr=self::hashImage($src); imagedestroy($src); return$hashStr; } /**比较两个hash值,是不是相似 *@paramstring$aHashA图片的hash值 *@paramstring$bHashB图片的hash值 *@returnbool当图片相似则传递true,否则是false **/ publicstaticfunctionisHashSimilar($aHash,$bHash){ $aL=strlen($aHash);$bL=strlen($bHash); if($aL!==$bL){returnfalse;} /*计算容许落差的数量*/ $allowGap=$aL*(100-self::$similarity)/100; /*计算两个hash值的汉明距离*/ $distance=0; for($i=0;$i<$aL;$i++){ if($aHash{$i}!==$bHash{$i}){$distance++;} } return($distance<=$allowGap)?true:false; } /**比较两个图片文件,是不是相似 *@paramstring$aHashA图片的路径 *@paramstring$bHashB图片的路径 *@returnbool当图片相似则传递true,否则是false **/ publicstaticfunctionisImageFileSimilar($aPath,$bPath){ $aHash=ImageHash::hashImageFile($aPath); $bHash=ImageHash::hashImageFile($bPath); returnImageHash::isHashSimilar($aHash,$bHash); } }