github.com/insionng/yougam@v0.0.0-20170714101924-2bc18d833463/helper/gopha.go (about) 1 package helper 2 3 import ( 4 "bytes" 5 "errors" 6 "fmt" 7 "image" 8 "os" 9 10 _ "image/gif" 11 _ "image/jpeg" 12 _ "image/png" 13 //"github.com/insionng/yougam/libraries/nfnt/resize" 14 ) 15 16 func PHA(m image.Image) string { 17 // Step 1: resize picture to 8*8. 18 //m = resize.Resize(8, 8, m, resize.NearestNeighbor) 19 m = Resize(m, m.Bounds(), 8, 8) 20 21 // Step 2: grayscale picture. 22 gray := grayscaleImg(m) 23 24 // Step 3: calculate average value. 25 avg := calAvgValue(gray) 26 27 // Step 4: get fingerprint. 28 fg := getFingerprint(avg, gray) 29 30 return string(fg) 31 } 32 33 // grayscaleImg converts picture to grayscale. 34 func grayscaleImg(src image.Image) []byte { 35 // Create a new grayscale image 36 bounds := src.Bounds() 37 w, h := bounds.Max.X, bounds.Max.Y 38 gray := make([]byte, w*h) 39 for x := 0; x < w; x++ { 40 for y := 0; y < h; y++ { 41 r, g, b, _ := src.At(x, y).RGBA() 42 gray[x+y*8] = byte((r*30 + g*59 + b*11) / 100) 43 } 44 } 45 return gray 46 } 47 48 // calAvgValue returns average value of color of picture. 49 func calAvgValue(gray []byte) byte { 50 sum := 0 51 for _, v := range gray { 52 sum += int(v) 53 } 54 return byte(sum / len(gray)) 55 } 56 57 // getFingerprint returns fingerprint of a picture. 58 func getFingerprint(avg byte, gray []byte) string { 59 var buf bytes.Buffer 60 for _, v := range gray { 61 if avg >= v { 62 buf.WriteByte('1') 63 } else { 64 buf.WriteByte('0') 65 } 66 } 67 return buf.String() 68 } 69 70 // Pha Compare 71 func CompareDiff(fg1, fg2 string) int { 72 diff := 0 73 fbyte := []byte(fg1) 74 fbyte2 := []byte(fg2) 75 for i, v := range fbyte { 76 if fbyte2[i] != v { 77 diff++ 78 } 79 } 80 return diff 81 } 82 83 //PHA算法 获取图像指纹 84 func GetImagePha(path string) (string, error) { 85 86 if infile, err := os.Open(path); err != nil { 87 return "", err 88 } else { 89 90 // Decode picture. 91 if srcImg, _, err := image.Decode(infile); err != nil { 92 fmt.Println("Decode picture:", err) 93 } else { 94 95 return PHA(srcImg), err 96 97 } 98 99 } 100 return "", errors.New("获取图片PHA值出现错误") 101 102 } 103 104 //指纹比较 105 func PhaCompare(path1 string, path2 string) (int, error) { 106 107 if fg1, err := GetImagePha(path1); err != nil { 108 return -1, err 109 } else { 110 if fg2, err := GetImagePha(path2); err != nil { 111 return -1, err 112 } else { 113 114 return CompareDiff(fg1, fg2), err 115 } 116 } 117 118 }