-
Notifications
You must be signed in to change notification settings - Fork 274
/
driver_math.go
143 lines (118 loc) · 3.24 KB
/
driver_math.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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
package base64Captcha
import (
"fmt"
"image/color"
"math/rand"
"strings"
"github.com/golang/freetype/truetype"
)
// DriverMath captcha config for captcha math
type DriverMath struct {
//Height png height in pixel.
Height int
// Width Captcha png width in pixel.
Width int
//NoiseCount text noise count.
NoiseCount int
//ShowLineOptions := OptionShowHollowLine | OptionShowSlimeLine | OptionShowSineLine .
ShowLineOptions int
//BgColor captcha image background color (optional)
BgColor *color.RGBA
//fontsStorage font storage (optional)
fontsStorage FontsStorage
//Fonts loads by name see fonts.go's comment
Fonts []string
fontsArray []*truetype.Font
}
// NewDriverMath creates a driver of math
func NewDriverMath(height int, width int, noiseCount int, showLineOptions int, bgColor *color.RGBA, fontsStorage FontsStorage, fonts []string) *DriverMath {
if fontsStorage == nil {
fontsStorage = DefaultEmbeddedFonts
}
tfs := []*truetype.Font{}
for _, fff := range fonts {
tf := fontsStorage.LoadFontByName("fonts/" + fff)
tfs = append(tfs, tf)
}
if len(tfs) == 0 {
tfs = fontsAll
}
return &DriverMath{Height: height, Width: width, NoiseCount: noiseCount, ShowLineOptions: showLineOptions, fontsArray: tfs, BgColor: bgColor, Fonts: fonts}
}
// ConvertFonts loads fonts from names
func (d *DriverMath) ConvertFonts() *DriverMath {
if d.fontsStorage == nil {
d.fontsStorage = DefaultEmbeddedFonts
}
tfs := []*truetype.Font{}
for _, fff := range d.Fonts {
tf := d.fontsStorage.LoadFontByName("fonts/" + fff)
tfs = append(tfs, tf)
}
if len(tfs) == 0 {
tfs = fontsAll
}
d.fontsArray = tfs
return d
}
// GenerateIdQuestionAnswer creates id,captcha content and answer
func (d *DriverMath) GenerateIdQuestionAnswer() (id, question, answer string) {
id = RandomId()
operators := []string{"+", "-", "x"}
var mathResult int32
switch operators[rand.Int31n(3)] {
case "+":
a := rand.Int31n(20)
b := rand.Int31n(20)
question = fmt.Sprintf("%d+%d=?", a, b)
mathResult = a + b
case "x":
a := rand.Int31n(10)
b := rand.Int31n(10)
question = fmt.Sprintf("%dx%d=?", a, b)
mathResult = a * b
default:
a := rand.Int31n(80) + rand.Int31n(20)
b := rand.Int31n(80)
question = fmt.Sprintf("%d-%d=?", a, b)
mathResult = a - b
}
answer = fmt.Sprintf("%d", mathResult)
return
}
// DrawCaptcha creates math captcha item
func (d *DriverMath) DrawCaptcha(question string) (item Item, err error) {
var bgc color.RGBA
if d.BgColor != nil {
bgc = *d.BgColor
} else {
bgc = RandLightColor()
}
itemChar := NewItemChar(d.Width, d.Height, bgc)
//波浪线 比较丑
if d.ShowLineOptions&OptionShowHollowLine == OptionShowHollowLine {
itemChar.drawHollowLine()
}
//背景有文字干扰
if d.NoiseCount > 0 {
noise := RandText(d.NoiseCount, strings.Repeat(TxtNumbers, d.NoiseCount))
err = itemChar.drawNoise(noise, fontsAll)
if err != nil {
return
}
}
//画 细直线 (n 条)
if d.ShowLineOptions&OptionShowSlimeLine == OptionShowSlimeLine {
itemChar.drawSlimLine(3)
}
//画 多个小波浪线
if d.ShowLineOptions&OptionShowSineLine == OptionShowSineLine {
itemChar.drawSineLine()
}
//draw question
err = itemChar.drawText(question, d.fontsArray)
if err != nil {
return
}
return itemChar, nil
}