Skip to content

Commit 8c89934

Browse files
committed
使用彩色验证码字符,提高人眼阅读体验
1 parent 84cd44e commit 8c89934

File tree

3 files changed

+69
-30
lines changed

3 files changed

+69
-30
lines changed

composer.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@
55
"captcha",
66
"anti robot"
77
],
8-
"version" : "1.1.1",
9-
"time" : "2019-11-17 02:26:00",
8+
"version" : "1.2.0",
9+
"time" : "2019-12-04 22:00:00",
1010
"require" : {
1111
"php" : ">=7.0",
1212
"ext-gd" : "*"

lib/Captcha.php

Lines changed: 65 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -26,14 +26,32 @@ class Captcha implements CaptchaInterface
2626
const LEVEL_NORMAL = 2;
2727
const LEVEL_HEIGHT = 3;
2828
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+
];
2947

3048
protected $cfg = [
3149
'curve' => 2, // 画混淆曲线数量
3250
'distort' => 3, // 扭曲级别(0-9),0为不扭曲,建议为验证码字体大小/6
3351
'length' => 4, // 验证码位数
3452
'fontSize' => 36, // 验证码字体大小(px)
35-
'bgColor' => [255, 255, 255],
36-
'color' => [0, 0, 0],
53+
'bgColor' => [255,255,255],
54+
'color' => [],
3755
];
3856

3957
/**
@@ -54,7 +72,7 @@ class Captcha implements CaptchaInterface
5472
*
5573
* @var string
5674
*/
57-
protected $phraseSet = '356789ABCDEFGHKLMNPQRSTUVWXY';
75+
protected $phraseSet = '23456789ABCDEFHKLMNPQRSTUVWXY';
5876

5977
/**
6078
* 验证码图片实例
@@ -70,6 +88,28 @@ class Captcha implements CaptchaInterface
7088

7189
private $phrase = '';
7290

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+
73113
/**
74114
* Captcha constructor.
75115
* @param array $cfg = <pre> [
@@ -82,6 +122,9 @@ class Captcha implements CaptchaInterface
82122
public function __construct(array $cfg = [])
83123
{
84124
$this->cfg = array_replace_recursive($this->cfg, $cfg);
125+
126+
$font = $cfg['font'] ?? dirname(__DIR__) . '/assets/font.ttf';
127+
$this->setFont($font);
85128
}
86129

87130
/**
@@ -96,18 +139,18 @@ public function setLevel(int $level) {
96139
$this->cfg['length'] = 4;
97140
break;
98141
case static::LEVEL_NORMAL:
99-
$this->cfg['curve'] = 2;
100-
$this->cfg['distort'] = 2;
142+
$this->cfg['curve'] = 1;
143+
$this->cfg['distort'] = 4;
101144
$this->cfg['length'] = 4;
102145
break;
103146
case static::LEVEL_HEIGHT:
104147
$this->cfg['curve'] = 2;
105-
$this->cfg['distort'] = 4;
148+
$this->cfg['distort'] = 5;
106149
$this->cfg['length'] = 5;
107150
break;
108151
case static::LEVEL_VERY_HEIGHT:
109152
$this->cfg['curve'] = 3;
110-
$this->cfg['distort'] = 5;
153+
$this->cfg['distort'] = 6;
111154
$this->cfg['length'] = 6;
112155
break;
113156
default :
@@ -155,51 +198,44 @@ public function create()
155198
// 建立一幅 $this->width x $this->height 的图像
156199
$this->image = imagecreate($this->width, $this->height);
157200

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]);
159203

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+
}
162206

163207
$this->phrase();
164208

165-
for ($i = 0; $i < $this->cfg['curve']; $i++) {
166-
$this->curve(); // 绘干扰线
167-
}
168-
169209
if ($this->cfg['distort']) {
170210
$this->distort(); // 扭曲验证码
171211
}
212+
213+
for ($i = 0; $i < $this->cfg['curve']; $i++) {
214+
$this->curve(); // 绘干扰线
215+
}
172216
}
173217

174218
/**
175219
* 绘制验证码字符
176220
*/
177221
protected function phrase()
178222
{
179-
// 验证码使用随机字体
180-
$ttf = dirname(__DIR__) . '/assets/font.ttf';
181-
182223
// 绘验证码
183224
$phrase = [];
184225

185226
$phraseNX = - $this->cfg['fontSize'] * 0.2; // 验证码第N个字符的左边距
186227

187228
for ($i = 0; $i<$this->cfg['length']; $i++) {
188229
$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;
197231

198232
// 倾斜度
199233
$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]);
200236

201237
// 绘制一个验证码字符
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]);
203239
}
204240

205241

@@ -232,6 +268,8 @@ protected function curve()
232268

233269
$px1 = mt_rand(0, $this->width/4); // 曲线横坐标起始位置
234270
$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]);
235273

236274
for ($px = $px1; $px <= $px2; $px ++) {
237275
if ($w == 0) {
@@ -241,7 +279,7 @@ protected function curve()
241279
$py = $A * sin($w*$px + $f)+ $b + $this->height/2; // y = Asin(ωx+φ) + b
242280
$i = max(2, intval($this->cfg['fontSize']/10));
243281
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循环)性能要好很多
245283
$i--;
246284
}
247285
}

test/demo.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@
55
use wf\captcha\Captcha;
66

77
$capt = new Captcha();
8-
$capt->setLevel(Captcha::LEVEL_HEIGHT);
8+
//$capt->setLevel(Captcha::LEVEL_HEIGHT);
9+
$capt->setLevel(Captcha::LEVEL_NORMAL);
910
$capt->create();
1011

1112
// set to session

0 commit comments

Comments
 (0)