說明:
最近有一個需求,說。一組圖片地址,如果兩張圖片相似,就進行去重。
例如:
如下圖,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。