forked from lucky41/entropy
/
captcha.go
72 lines (65 loc) · 1.39 KB
/
captcha.go
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
package entropy
import (
"image"
"image/draw"
"io/ioutil"
"math/rand"
"time"
"code.google.com/p/freetype-go/freetype"
"code.google.com/p/freetype-go/freetype/truetype"
)
const (
WORDPOOL = "ABCDEFGHJKMNPQRSTUVWXYZ23456789"
)
type Captcha struct {
Image *image.RGBA
Text string
}
/*
生成验证码
bg:背景色
fg:前景色
length:字符长度
width:宽度
height:高度
size:字体大小
fontPath:字体文件路径
*/
func GenerateCaptcha(bg, fg *image.Uniform, length int, width int, height int, size float64, fontPath string) *Captcha {
fontBytes, err := ioutil.ReadFile(fontPath)
if err != nil {
panic(err)
}
font, err := truetype.Parse(fontBytes)
if err != nil {
panic(err)
}
cap := &Captcha{}
cap.Text = randString(length)
cap.Image = image.NewRGBA(image.Rect(0, 0, width, height))
draw.Draw(cap.Image, cap.Image.Bounds(), bg, image.ZP, draw.Src)
c := freetype.NewContext()
c.SetFont(font)
c.SetFontSize(size)
c.SetClip(cap.Image.Bounds())
c.SetDst(cap.Image)
c.SetSrc(fg)
pt := freetype.Pt(0, int(c.PointToFix32(size)>>8))
for _, s := range cap.Text {
_, err = c.DrawString(string(s), pt)
if err != nil {
panic(err)
return nil
}
pt.X += c.PointToFix32(size * 0.5)
}
return cap
}
func randString(length int) string {
ret := ""
rand.Seed(time.Now().UnixNano())
for i := 0; i < length; i++ {
ret += string(WORDPOOL[rand.Intn(len(WORDPOOL))])
}
return ret
}