PHP实现的简易版图片相似度比较


Posted in PHP onJanuary 07, 2015

由于相似图片搜索的php实现的 API 不怎么符合我的用途,所以我重新定义 API 的架构,改写成比较简单的函数方式,虽然还是用对象的方式包装。

<?php    

/**   

* 图片相似度比较   

*   

* @version     $Id: ImageHash.php 4429 2012-04-17 13:20:31Z jax $   

* @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>   

*/    

    

class ImageHash {    

    

   /**取样倍率 1~10   

    * @access public   

    * @staticvar int   

    * */    

   public static $rate = 2;    

    

   /**相似度允许值 0~64   

    * @access public   

    * @staticvar int   

    * */    

   public static $similarity = 80;    

    

   /**图片类型对应的开启函数   

    * @access private   

    * @staticvar string   

    * */    

   private static $_createFunc = array(    

       IMAGETYPE_GIF   =>'imageCreateFromGIF',    

       IMAGETYPE_JPEG  =>'imageCreateFromJPEG',    

       IMAGETYPE_PNG   =>'imageCreateFromPNG',    

       IMAGETYPE_BMP   =>'imageCreateFromBMP',    

       IMAGETYPE_WBMP  =>'imageCreateFromWBMP',    

       IMAGETYPE_XBM   =>'imageCreateFromXBM',    

   );    

    

    

   /**从文件建立图片   

    * @param string $filePath 文件地址路径   

    * @return resource 当成功开启图片则传递图片 resource ID,失败则是 false   

    * */    

   public static function createImage($filePath){    

       if(!file_exists($filePath)){ return false; }    

    

       /*判断文件类型是否可以开启*/    

       $type = exif_imagetype($filePath);    

       if(!array_key_exists($type,self::$_createFunc)){ return false; }    

    

       $func = self::$_createFunc[$type];    

       if(!function_exists($func)){ return false; }    

    

       return $func($filePath);    

   }    

    

    

   /**hash 图片   

    * @param resource $src 图片 resource ID   

    * @return string 图片 hash 值,失败则是 false   

    * */    

   public static function hashImage($src){    

       if(!$src){ return false; }    

    

       /*缩小图片尺寸*/    

       $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 ($grayArray as $gray){    

           $hashStr .= ($gray>=$average) ? '1' : '0';    

       }    

    

       return $hashStr;    

   }    

    

    

   /**hash 图片文件   

    * @param string $filePath 文件地址路径   

    * @return string 图片 hash 值,失败则是 false   

    * */    

   public static function hashImageFile($filePath){    

       $src = self::createImage($filePath);    

       $hashStr = self::hashImage($src);    

       imagedestroy($src);    

    

       return $hashStr;    

   }    

    

    

   /**比较两个 hash 值,是不是相似   

    * @param string $aHash A图片的 hash 值   

    * @param string $bHash B图片的 hash 值   

    * @return bool 当图片相似则传递 true,否则是 false   

    * */    

   public static function isHashSimilar($aHash, $bHash){    

       $aL = strlen($aHash); $bL = strlen($bHash);    

       if ($aL !== $bL){ return false; }    

    

       /*计算容许落差的数量*/    

       $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;    

   }    

    

    

   /**比较两个图片文件,是不是相似   

    * @param string $aHash A图片的路径   

    * @param string $bHash B图片的路径   

    * @return bool 当图片相似则传递 true,否则是 false   

    * */    

   public static function isImageFileSimilar($aPath, $bPath){    

       $aHash = ImageHash::hashImageFile($aPath);    

       $bHash = ImageHash::hashImageFile($bPath);    

       return ImageHash::isHashSimilar($aHash, $bHash);    

   }    

    

} 
PHP 相关文章推荐
PHP与已存在的Java应用程序集成
Oct 09 PHP
Linux下进行MYSQL编程时插入中文乱码的解决方案
Mar 15 PHP
PHP,ASP.JAVA,JAVA代码格式化工具整理
Jun 15 PHP
用穿越火线快速入门php面向对象
Feb 22 PHP
基于PHP字符串的比较函数strcmp()与strcasecmp()的使用详解
May 15 PHP
php设计模式之简单工厂模式详解
Sep 04 PHP
PHP5多态性与动态绑定介绍
Apr 03 PHP
帝国cms常用标签汇总
Jul 06 PHP
记录一次排查PHP脚本执行卡住的问题
Dec 27 PHP
thinkphp3.2实现在线留言提交验证码功能
Jul 19 PHP
PHP+Ajax实现上传文件进度条动态显示进度功能
Jun 04 PHP
thinkPHP实现基于ajax的评论回复功能
Jun 22 PHP
PHP中使用SimpleXML检查XML文件结构实例
Jan 07 #PHP
php中$_POST与php://input的区别实例分析
Jan 07 #PHP
php静态文件返回304技巧分享
Jan 06 #PHP
php判断当前用户已在别处登录的方法
Jan 06 #PHP
php实现utf-8转unicode函数分享
Jan 06 #PHP
windows中为php安装mongodb与memcache
Jan 06 #PHP
phpQuery让php处理html代码像jQuery一样方便
Jan 06 #PHP
You might like
php daodb插入、更新与删除数据
2009/03/19 PHP
PHP里的中文变量说明
2011/07/23 PHP
php解析字符串里所有URL地址的方法
2015/04/03 PHP
跨浏览器开发经验总结(四) 怎么写入剪贴板
2010/05/13 Javascript
jquery 图片轮换效果
2010/07/29 Javascript
js取float型小数点后两位数的方法
2014/01/18 Javascript
AngularJS学习笔记之TodoMVC的分析
2015/02/22 Javascript
jQuery实现每隔几条元素增加1条线的方法
2016/06/27 Javascript
TypeScript入门-基本数据类型
2017/03/28 Javascript
深入理解JavaScript 参数按值传递
2017/05/24 Javascript
11行JS代码制作二维码生成功能
2018/03/09 Javascript
Webpack的dll功能使用
2018/06/28 Javascript
Vue瀑布流插件的使用示例
2018/09/19 Javascript
详解JavaScript原生封装ajax请求和Jquery中的ajax请求
2019/02/14 jQuery
Vue formData实现图片上传
2019/08/20 Javascript
Python HTTP客户端自定义Cookie实现实例
2017/04/28 Python
Python实现的排列组合计算操作示例
2017/10/13 Python
完美解决在oj中Python的循环输入问题
2018/06/25 Python
Anaconda的安装与虚拟环境建立
2020/11/18 Python
浅析Python的命名空间与作用域
2020/11/25 Python
纯CSS3实现的8种Loading动画效果
2014/07/05 HTML / CSS
详解通过focusout事件解决IOS键盘收起时界面不归位的问题
2019/07/18 HTML / CSS
世界首屈一指的在线男士内衣权威:HisRoom
2017/08/05 全球购物
Mamas & Papas沙特阿拉伯:英国最受欢迎的婴儿品牌
2017/11/20 全球购物
专升本个人自我评价
2013/12/22 职场文书
物理学专业求职信
2014/07/04 职场文书
工商局副局长个人对照检查材料
2014/09/25 职场文书
2014班子成员自我剖析材料思想汇报
2014/10/01 职场文书
债务纠纷委托书范本
2014/10/14 职场文书
幼儿园教师自荐书
2015/03/06 职场文书
实验心得体会范文
2016/01/25 职场文书
环境保护宣传标语大全!
2019/06/28 职场文书
为什么阅读对所有年龄段的孩子都很重要?
2019/07/08 职场文书
python中Matplotlib绘制直线的实例代码
2021/07/04 Python
选购到合适的激光打印机
2022/04/21 数码科技
Python面试不修改数组找出重复的数字
2022/05/20 Python