说明:
最近有一个需求,说。一组图片地址,如果两张图片相似,就进行去重。
例如:
如下图,img_list 中,如果第一个和第二个,图片相同,那么就保留其中一个,其余的依次类推,最终取的一个不重复的,图片img_listing。
思路:
至于图片怎么识别为重复的,这里使用的是一个扩展,扩展git地址:https://github.com/jenssegers/imagehash
这个利用的是,图像哈希。
Laravel安装扩展
composer require jenssegers/imagehash
去重思路:
1、N张图片对比后去重,这里就需要每两两进行比较,如果重复,就删除一张。所以,这里两两的组合比对次数为 ((n-1)*n )/2。这其实就是一个握手计数原理。
2、所以,我们可以按这个逻辑进行写代码。
步骤一:定义一个方法,传入需要对比的图片地址数组;
步骤二:使用两层for循环,计算出所有的组合数;
步骤三:对二中的组合进行哈希比对,如果为重复,即删除第一个键名内容,然后,将删除后的数组再传入到该方法中,如此进行递归调用,最后取的没有重复的数组img。
代码如下:
/**
* 删除数组中相似的图片地址方法
* $img_list 图片数组list
* $img_count 数组长度
* $img_hash 图片地址与的散列值的映射数组,承载,减少重复处理次数,优化处理时间
*/
public function deleteSha1Img($img_list, $img_count, $img_hash = []){
try{
$hasher = new ImageHash(new DifferenceHash());
//两层循环,使用握手计数原理,计算出两两图片对比的组合
for ($i=0; $i < $img_count; $i++) {
for ($i1 = $img_count - 1; $i1 > $i; $i1 --) {
if(empty($img_hash[$img_list[$i]])){//承载数组中,没有,直接获取
$value1_sh = $hasher->hash($img_list[$i]);//获取图片的散列值对象 $hash->toHex();
$img_hash[$img_list[$i]] = $value1_sh;//进行赋值
}else{
$value1_sh = $img_hash[$img_list[$i]];//有,直接读取
}
if(empty($img_hash[$img_list[$i1]])){
$value2_sh = $hasher->hash($img_list[$i1]);
$img_hash[$img_list[$i1]] = $value2_sh;
}else{
$value2_sh = $img_hash[$img_list[$i1]];
}
$sh = $hasher->distance($value1_sh, $value2_sh);//进行相似比较
if($sh <= 5){
unset($img_list[$i]);//两张相似的,直接删除第一张
$img_list = array_values($img_list);//对新数组进行重新排序
return $this->deleteSha1Img($img_list, count($img_list), $img_hash);
}
}
}
}catch(\Exception $e){
throw new \Exception($e->getMessage());
}
return $img_list;
}
结束:
记录一下,发现最近经常写递归,递归注意返回值,不然会出现,明明有值,却调用的时候,返回null。
-----END