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  }