@@ -26,14 +26,32 @@ class Captcha implements CaptchaInterface
26
26
const LEVEL_NORMAL = 2 ;
27
27
const LEVEL_HEIGHT = 3 ;
28
28
const LEVEL_VERY_HEIGHT = 4 ;
29
+ const COLORS = [
30
+ [0x00 , 0x00 , 0x80 ], // navy
31
+ [0x00 , 0x00 , 0xFF ], // blue
32
+ [0x00 , 0xFF , 0xFF ], // aqua
33
+ [0x00 , 0x80 , 0x80 ], // teal
34
+ [0x80 , 0x80 , 0x00 ], // olive
35
+ [0x00 , 0x80 , 0x00 ], // green
36
+ [0x00 , 0xFF , 0x00 ], // lime
37
+ [0xFF , 0x00 , 0x00 ], // yellow
38
+ [0xFF , 0xA5 , 0x00 ], // orange
39
+ [0xFF , 0x00 , 0x00 ], // red
40
+ [0x80 , 0x00 , 0x00 ], // maroon
41
+ [0xFF , 0x00 , 0xFF ], // fuchsia
42
+ [0x80 , 0x00 , 0x80 ], // purple
43
+ [0x00 , 0x00 , 0xC0 ], // black
44
+ [0x80 , 0x80 , 0x80 ], // gray
45
+ [0xC0 , 0xC0 , 0xC0 ], // silver
46
+ ];
29
47
30
48
protected $ cfg = [
31
49
'curve ' => 2 , // 画混淆曲线数量
32
50
'distort ' => 3 , // 扭曲级别(0-9),0为不扭曲,建议为验证码字体大小/6
33
51
'length ' => 4 , // 验证码位数
34
52
'fontSize ' => 36 , // 验证码字体大小(px)
35
- 'bgColor ' => [255 , 255 , 255 ],
36
- 'color ' => [0 , 0 , 0 ],
53
+ 'bgColor ' => [255 ,255 ,255 ],
54
+ 'color ' => [],
37
55
];
38
56
39
57
/**
@@ -54,7 +72,7 @@ class Captcha implements CaptchaInterface
54
72
*
55
73
* @var string
56
74
*/
57
- protected $ phraseSet = '356789ABCDEFGHKLMNPQRSTUVWXY ' ;
75
+ protected $ phraseSet = '23456789ABCDEFHKLMNPQRSTUVWXY ' ;
58
76
59
77
/**
60
78
* 验证码图片实例
@@ -70,6 +88,28 @@ class Captcha implements CaptchaInterface
70
88
71
89
private $ phrase = '' ;
72
90
91
+ /**
92
+ * @var string
93
+ */
94
+ private $ font ;
95
+
96
+ /**
97
+ * @return string
98
+ */
99
+ public function getFont (): string
100
+ {
101
+ return $ this ->font ;
102
+ }
103
+
104
+ /**
105
+ * @param string $font
106
+ */
107
+ public function setFont (string $ font )
108
+ {
109
+ $ this ->font = $ font ;
110
+ }
111
+
112
+
73
113
/**
74
114
* Captcha constructor.
75
115
* @param array $cfg = <pre> [
@@ -82,6 +122,9 @@ class Captcha implements CaptchaInterface
82
122
public function __construct (array $ cfg = [])
83
123
{
84
124
$ this ->cfg = array_replace_recursive ($ this ->cfg , $ cfg );
125
+
126
+ $ font = $ cfg ['font ' ] ?? dirname (__DIR__ ) . '/assets/font.ttf ' ;
127
+ $ this ->setFont ($ font );
85
128
}
86
129
87
130
/**
@@ -96,18 +139,18 @@ public function setLevel(int $level) {
96
139
$ this ->cfg ['length ' ] = 4 ;
97
140
break ;
98
141
case static ::LEVEL_NORMAL :
99
- $ this ->cfg ['curve ' ] = 2 ;
100
- $ this ->cfg ['distort ' ] = 2 ;
142
+ $ this ->cfg ['curve ' ] = 1 ;
143
+ $ this ->cfg ['distort ' ] = 4 ;
101
144
$ this ->cfg ['length ' ] = 4 ;
102
145
break ;
103
146
case static ::LEVEL_HEIGHT :
104
147
$ this ->cfg ['curve ' ] = 2 ;
105
- $ this ->cfg ['distort ' ] = 4 ;
148
+ $ this ->cfg ['distort ' ] = 5 ;
106
149
$ this ->cfg ['length ' ] = 5 ;
107
150
break ;
108
151
case static ::LEVEL_VERY_HEIGHT :
109
152
$ this ->cfg ['curve ' ] = 3 ;
110
- $ this ->cfg ['distort ' ] = 5 ;
153
+ $ this ->cfg ['distort ' ] = 6 ;
111
154
$ this ->cfg ['length ' ] = 6 ;
112
155
break ;
113
156
default :
@@ -155,51 +198,44 @@ public function create()
155
198
// 建立一幅 $this->width x $this->height 的图像
156
199
$ this ->image = imagecreate ($ this ->width , $ this ->height );
157
200
158
- imagecolorallocate ($ this ->image , $ this ->cfg ['bgColor ' ][0 ], $ this ->cfg ['bgColor ' ][1 ], $ this ->cfg ['bgColor ' ][2 ]);
201
+ $ bgColor = $ this ->cfg ['bgColor ' ] ? $ this ->cfg ['bgColor ' ] : [mt_rand (0x70 , 0xff ), mt_rand (0x70 , 0xff ), mt_rand (0x70 , 0xff )];
202
+ imagecolorallocate ($ this ->image , $ bgColor [0 ], $ bgColor [1 ], $ bgColor [2 ]);
159
203
160
- // 验证码字体随机颜色
161
- $ this -> color = imagecolorallocate ( $ this -> image , $ this -> cfg [ ' color ' ][ 0 ], $ this -> cfg [ ' color ' ][ 1 ], $ this -> cfg [ ' color ' ][ 2 ]);
204
+ if ( $ this -> cfg [ ' color ' ]) {
205
+ }
162
206
163
207
$ this ->phrase ();
164
208
165
- for ($ i = 0 ; $ i < $ this ->cfg ['curve ' ]; $ i ++) {
166
- $ this ->curve (); // 绘干扰线
167
- }
168
-
169
209
if ($ this ->cfg ['distort ' ]) {
170
210
$ this ->distort (); // 扭曲验证码
171
211
}
212
+
213
+ for ($ i = 0 ; $ i < $ this ->cfg ['curve ' ]; $ i ++) {
214
+ $ this ->curve (); // 绘干扰线
215
+ }
172
216
}
173
217
174
218
/**
175
219
* 绘制验证码字符
176
220
*/
177
221
protected function phrase ()
178
222
{
179
- // 验证码使用随机字体
180
- $ ttf = dirname (__DIR__ ) . '/assets/font.ttf ' ;
181
-
182
223
// 绘验证码
183
224
$ phrase = [];
184
225
185
226
$ phraseNX = - $ this ->cfg ['fontSize ' ] * 0.2 ; // 验证码第N个字符的左边距
186
227
187
228
for ($ i = 0 ; $ i <$ this ->cfg ['length ' ]; $ i ++) {
188
229
$ phrase [$ i ] = $ this ->phraseSet [mt_rand (0 , strlen ($ this ->phraseSet )-1 )];
189
- if ($ i > 0 && in_array ($ phrase [$ i -1 ], ['I ' , 'J ' ])) {
190
- // 最宽的 MW
191
- $ phraseNX += $ this ->cfg ['fontSize ' ]*0.5 ;
192
- } elseif ($ i > 0 && in_array ($ phrase [$ i -1 ], ['M ' , 'W ' ])) {
193
- $ phraseNX += $ this ->cfg ['fontSize ' ]*0.8 ;
194
- } else {
195
- $ phraseNX += $ this ->cfg ['fontSize ' ]*0.65 ;
196
- }
230
+ $ phraseNX += $ this ->cfg ['fontSize ' ]*0.65 ;
197
231
198
232
// 倾斜度
199
233
$ gradient = mt_rand (-22 , 22 );
234
+ $ colorRGB = self ::COLORS [mt_rand (0 , count (self ::COLORS ) - 1 )];
235
+ $ color = imagecolorallocate ($ this ->image , $ colorRGB [0 ], $ colorRGB [1 ], $ colorRGB [2 ]);
200
236
201
237
// 绘制一个验证码字符
202
- imagettftext ($ this ->image , $ this ->cfg ['fontSize ' ], $ gradient , $ phraseNX , $ this ->cfg ['fontSize ' ]*1.1 , $ this -> color , $ ttf , $ phrase [$ i ]);
238
+ imagettftext ($ this ->image , $ this ->cfg ['fontSize ' ], $ gradient , $ phraseNX , $ this ->cfg ['fontSize ' ]*1.1 , $ color , $ this -> getFont () , $ phrase [$ i ]);
203
239
}
204
240
205
241
@@ -232,6 +268,8 @@ protected function curve()
232
268
233
269
$ px1 = mt_rand (0 , $ this ->width /4 ); // 曲线横坐标起始位置
234
270
$ px2 = mt_rand ($ px1 + $ this ->width /3 , $ this ->width ); // 曲线横坐标结束位置
271
+ $ colorRGB = self ::COLORS [mt_rand (0 , count (self ::COLORS ) - 1 )];
272
+ $ color = imagecolorallocate ($ this ->image , $ colorRGB [0 ], $ colorRGB [1 ], $ colorRGB [2 ]);
235
273
236
274
for ($ px = $ px1 ; $ px <= $ px2 ; $ px ++) {
237
275
if ($ w == 0 ) {
@@ -241,7 +279,7 @@ protected function curve()
241
279
$ py = $ A * sin ($ w *$ px + $ f )+ $ b + $ this ->height /2 ; // y = Asin(ωx+φ) + b
242
280
$ i = max (2 , intval ($ this ->cfg ['fontSize ' ]/10 ));
243
281
while ($ i > 0 ) {
244
- imagesetpixel ($ this ->image , $ px , $ py + $ i , $ this -> color ); // 这里(while)循环画像素点比imagettftext和imagestring用字体大小一次画出(不用这while循环)性能要好很多
282
+ imagesetpixel ($ this ->image , $ px , $ py + $ i , $ color ); // 这里(while)循环画像素点比imagettftext和imagestring用字体大小一次画出(不用这while循环)性能要好很多
245
283
$ i --;
246
284
}
247
285
}
0 commit comments