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);
}
}