感知哈希算法
count < =5 匹配最相似
count > 10 两张不同的图片
var_dump(ImageHash::run(‘./1.png', ‘./psb.jpg'));
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
|
<?php
class ImageHash {
const FILE_NOT_FOUND = '-1' ;
const FILE_EXTNAME_ILLEGAL = '-2' ;
private function __construct() {}
public static function run( $src1 , $src2 ) {
static $self ;
if (! $self ) $self = new static ;
if (! is_file ( $src1 ) || ! is_file ( $src2 )) exit (self::FILE_NOT_FOUND);
$hash1 = $self ->getHashValue( $src1 );
$hash2 = $self ->getHashValue( $src2 );
if ( strlen ( $hash1 ) !== strlen ( $hash2 )) return false;
$count = 0;
$len = strlen ( $hash1 );
for ( $i = 0; $i < $len ; $i ++) if ( $hash1 [ $i ] !== $hash2 [ $i ]) $count ++;
return $count <= 10 ? true : false;
}
public function getImage( $file ) {
$extname = pathinfo ( $file , PATHINFO_EXTENSION);
if (!in_array( $extname , [ 'jpg' , 'jpeg' , 'png' , 'gif' ])) exit (self::FILE_EXTNAME_ILLEGAL);
$img = call_user_func( 'imagecreatefrom' . ( $extname == 'jpg' ? 'jpeg' : $extname ) , $file );
return $img ;
}
public function getHashValue( $file ) {
$w = 8;
$h = 8;
$img = imagecreatetruecolor( $w , $h );
list( $src_w , $src_h ) = getimagesize ( $file );
$src = $this ->getImage( $file );
imagecopyresampled( $img , $src , 0, 0, 0, 0, $w , $h , $src_w , $src_h );
imagedestroy( $src );
$total = 0;
$array = array ();
for ( $y = 0; $y < $h ; $y ++) {
for ( $x = 0; $x < $w ; $x ++) {
$gray = (imagecolorat( $img , $x , $y ) >> 8) & 0xFF;
if (!isset( $array [ $y ])) $array [ $y ] = array ();
$array [ $y ][ $x ] = $gray ;
$total += $gray ;
}
}
imagedestroy( $img );
$average = intval ( $total / ( $w * $h * 2));
$hash = '' ;
for ( $y = 0; $y < $h ; $y ++) {
for ( $x = 0; $x < $w ; $x ++) {
$hash .= ( $array [ $y ][ $x ] >= $average ) ? '1' : '0' ;
}
}
var_dump( $hash );
return $hash ;
}
}
var_dump(ImageHash::run( './1.png' , './psb.jpg' ));
|
方法二:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
|
hash( $f );
}
return $isString ? $result [0] : $result ;
}
public function checkIsSimilarImg( $imgHash , $otherImgHash ){
if ( file_exists ( $imgHash ) && file_exists ( $otherImgHash )){
$imgHash = $this ->run( $imgHash );
$otherImgHash = $this ->run( $otherImgHash );
}
if ( strlen ( $imgHash ) !== strlen ( $otherImgHash )) return false;
$count = 0;
$len = strlen ( $imgHash );
for ( $i =0; $i < $len ; $i ++){
if ( $imgHash { $i } !== $otherImgHash { $i }){
$count ++;
}
}
return $count <= (5 * $rate * $rate ) ? true : false;
}
public function hash( $file ){
if (! file_exists ( $file )){
return false;
}
$height = 8 * $this ->rate;
$width = 8 * $this ->rate;
$img = imagecreatetruecolor( $width , $height );
list( $w , $h ) = getimagesize ( $file );
$source = $this ->createImg( $file );
imagecopyresampled( $img , $source , 0, 0, 0, 0, $width , $height , $w , $h );
$value = $this ->getHashValue( $img );
imagedestroy( $img );
return $value ;
}
public function getHashValue( $img ){
$width = imagesx( $img );
$height = imagesy( $img );
$total = 0;
$array = array ();
for ( $y =0; $y < $height ; $y ++){
for ( $x =0; $x < $width ; $x ++){
$gray = ( imagecolorat( $img , $x , $y ) >> 8 ) & 0xFF;
if (! is_array ( $array [ $y ])){
$array [ $y ] = array ();
}
$array [ $y ][ $x ] = $gray ;
$total += $gray ;
}
}
$average = intval ( $total / (64 * $this ->rate * $this ->rate));
$result = '' ;
for ( $y =0; $y < $height ; $y ++){
for ( $x =0; $x < $width ; $x ++){
if ( $array [ $y ][ $x ] >= $average ){
$result .= '1' ;
} else {
$result .= '0' ;
}
}
}
return $result ;
}
public function createImg( $file ){
$ext = $this ->getFileExt( $file );
if ( $ext === 'jpeg' ) $ext = 'jpg' ;
$img = null;
switch ( $ext ){
case 'png' : $img = imagecreatefrompng( $file ); break ;
case 'jpg' : $img = imagecreatefromjpeg( $file ); break ;
case 'gif' : $img = imagecreatefromgif( $file );
}
return $img ;
}
public function getFileExt( $file ){
$infos = explode ( '.' , $file );
$ext = strtolower ( $infos [ count ( $infos ) - 1]);
return $ext ;
}
}
|
调用方式如下:
1
2
3
|
require_once "Imghash.class.php" ;
$instance = ImgHash::getInstance();
$result = $instance ->checkIsSimilarImg( 'chenyin/IMG_3214.png' , 'chenyin/IMG_3212.JPG' );
|
如果$result值为true, 则表明2个图片相似,否则不相似。