感知哈希算法
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个图片相似,否则不相似。