github.com/insionng/yougam@v0.0.0-20170714101924-2bc18d833463/libraries/gopha/gopha.go (about) 1 // Copyright 2013 Unknown 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"): you may 4 // not use this file except in compliance with the License. You may obtain 5 // a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 11 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12 // License for the specific language governing permissions and limitations 13 // under the License. 14 15 // Package gopha is an implementation of Perceptual Hash Algorithm in Go programming language. 16 package gopha 17 18 import ( 19 "bytes" 20 "image" 21 22 //"github.com/insionng/yougam/libraries/nfnt/resize" 23 ) 24 25 func PHA(m image.Image) string { 26 // Step 1: resize picture to 8*8. 27 //m = resize.Resize(8, 8, m, resize.NearestNeighbor) 28 m = Resize(m, m.Bounds(), 8, 8) 29 30 // Step 2: grayscale picture. 31 gray := grayscaleImg(m) 32 33 // Step 3: calculate average value. 34 avg := calAvgValue(gray) 35 36 // Step 4: get fingerprint. 37 fg := getFingerprint(avg, gray) 38 39 return string(fg) 40 } 41 42 // grayscaleImg converts picture to grayscale. 43 func grayscaleImg(src image.Image) []byte { 44 // Create a new grayscale image 45 bounds := src.Bounds() 46 w, h := bounds.Max.X, bounds.Max.Y 47 gray := make([]byte, w*h) 48 for x := 0; x < w; x++ { 49 for y := 0; y < h; y++ { 50 r, g, b, _ := src.At(x, y).RGBA() 51 gray[x+y*8] = byte((r*30 + g*59 + b*11) / 100) 52 } 53 } 54 return gray 55 } 56 57 // calAvgValue returns average value of color of picture. 58 func calAvgValue(gray []byte) byte { 59 sum := 0 60 for _, v := range gray { 61 sum += int(v) 62 } 63 return byte(sum / len(gray)) 64 } 65 66 // getFingerprint returns fingerprint of a picture. 67 func getFingerprint(avg byte, gray []byte) string { 68 var buf bytes.Buffer 69 for _, v := range gray { 70 if avg >= v { 71 buf.WriteByte('1') 72 } else { 73 buf.WriteByte('0') 74 } 75 } 76 return buf.String() 77 }