-
Notifications
You must be signed in to change notification settings - Fork 9
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
5c695cc
commit aa5487f
Showing
2 changed files
with
65 additions
and
110 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -30,7 +30,6 @@ class Config extends SplBean | |
public $imageH = null; // 图片高度 | ||
public $fonts = []; // 额外字体 | ||
public $fontSize = 25; // 字体大小 | ||
public $length = 4; // 生成位数 | ||
public $mime = MIME::PNG; // 设置类型 | ||
public $temp = '/tmp'; // 设置缓存目录 | ||
|
||
|
@@ -147,14 +146,16 @@ public function setImageHeight($imageH) | |
* @param array|string $fonts | ||
* @return Config | ||
*/ | ||
public function setFonts($fonts) | ||
public function addFonts($fonts) | ||
{ | ||
if (is_string($fonts)) array_push($this->fonts, $fonts); | ||
if (is_string($fonts)) { | ||
$this->fonts[] = $fonts; | ||
} | ||
if (is_array($fonts) && !empty($fonts)) { | ||
if (empty($this->fonts)) { | ||
$this->fonts = $fonts; | ||
} else { | ||
array_merge($this->fonts, $fonts); | ||
$this->fonts = array_merge($this->fonts, $fonts); | ||
} | ||
} | ||
return $this; | ||
|
@@ -171,27 +172,6 @@ public function setFontSize($fontSize) | |
return $this; | ||
} | ||
|
||
/** | ||
* 设置验证码长度 | ||
* @param int $length | ||
* @return Config | ||
*/ | ||
public function setLength($length) | ||
{ | ||
$this->length = intval($length); | ||
return $this; | ||
} | ||
|
||
/** | ||
* 获取配置值 | ||
* @param $name | ||
* @author : evalor <[email protected]> | ||
* @return mixed | ||
*/ | ||
public function __get($name) | ||
{ | ||
return $this->$name; | ||
} | ||
|
||
/** | ||
* 十六进制转RGB | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7,89 +7,75 @@ | |
*/ | ||
class VerifyCode | ||
{ | ||
protected $conf; | ||
protected Config $conf; | ||
protected $imInstance; | ||
private int $length; | ||
|
||
/** | ||
* VerifyCode constructor. | ||
* @param null $options | ||
*/ | ||
public function __construct($options = null) | ||
protected mixed $useFont; | ||
|
||
public function __construct(Config $option = null) | ||
{ | ||
// 传入了配置则使用配置文件 | ||
$this->conf = $options instanceof Config ? $options : new Config; | ||
$assetsPath = __DIR__ . '/assets/'; | ||
|
||
// 合并字体库 | ||
$fonts = $this->loadFonts($assetsPath . 'ttf/'); | ||
if ($this->fonts) $fonts = array_merge($fonts, $this->fonts); | ||
|
||
// 初始化配置项 | ||
$this->useFont || $this->useFont = $fonts[array_rand($fonts)]; | ||
$this->imageL || $this->imageL = $this->length * $this->fontSize * 1.5 + $this->fontSize / 2; | ||
$this->imageH || $this->imageH = $this->fontSize * 2; | ||
$this->fontColor || $this->fontColor = [mt_rand(1, 150), mt_rand(1, 150), mt_rand(1, 150)]; | ||
$this->backColor || $this->backColor = [255, 255, 255]; | ||
if($option == null){ | ||
$this->conf = new Config(); | ||
}else{ | ||
$this->conf = $option; | ||
} | ||
|
||
if($this->conf->useFont){ | ||
$this->useFont = $this->conf->useFont; | ||
}else{ | ||
$assetsPath = __DIR__ . '/assets/'; | ||
$fonts = $this->loadFonts($assetsPath . 'ttf/'); | ||
$this->conf->addFonts($fonts); | ||
$fonts = $this->conf->fonts; | ||
$this->useFont = $fonts[array_rand($fonts)]; | ||
} | ||
|
||
$this->conf->fontColor || $this->conf->fontColor = [mt_rand(1, 150), mt_rand(1, 150), mt_rand(1, 150)]; | ||
$this->conf->backColor || $this->conf->backColor = [255, 255, 255]; | ||
} | ||
|
||
/** | ||
* 画验证码 | ||
* @author : evalor <[email protected]> | ||
* @param string $Code 画指定的验证码 | ||
* @return Result | ||
*/ | ||
function DrawCode($Code = null) | ||
|
||
function drawCode(string $code): Result | ||
{ | ||
// 如果传入了验证码则要重置参数 | ||
if (!is_null($Code)) { | ||
$this->length = strlen($Code); | ||
$this->imageL || $this->imageL = $this->length * $this->fontSize * 1.5 + $this->fontSize / 2; | ||
$this->imageH || $this->imageH = $this->fontSize * 2; | ||
} else { | ||
$Code = substr(str_shuffle($this->charset), 0, $this->length); | ||
} | ||
$codeLen = strlen($code); | ||
$this->conf->imageL = $codeLen * $this->conf->fontSize * 1.5 + $this->conf->fontSize / 2; | ||
$this->conf->imageH = $this->conf->fontSize * 2; | ||
|
||
|
||
$Code = strval($Code); | ||
|
||
// 创建空白画布 | ||
$this->imInstance = imagecreate((int)$this->imageL, (int)$this->imageH); | ||
$this->imInstance = imagecreate((int)$this->conf->imageL, (int)$this->conf->imageH); | ||
// 设置背景颜色 | ||
$this->backColor = imagecolorallocate($this->imInstance, $this->backColor[0], $this->backColor[1], $this->backColor[2]); | ||
$this->conf->backColor = imagecolorallocate($this->imInstance, $this->conf->backColor[0], $this->conf->backColor[1], $this->conf->backColor[2]); | ||
// 设置字体颜色 | ||
$this->fontColor = imagecolorallocate($this->imInstance, $this->fontColor[0], $this->fontColor[1], $this->fontColor[2]); | ||
$this->conf->fontColor = imagecolorallocate($this->imInstance, $this->conf->fontColor[0], $this->conf->fontColor[1], $this->conf->fontColor[2]); | ||
// 画干扰噪点 | ||
if ($this->useNoise) $this->writeNoise(); | ||
if ($this->conf->useNoise) $this->writeNoise(); | ||
// 画干扰曲线 | ||
if ($this->useCurve) $this->writeCurve(); | ||
if ($this->conf->useCurve) $this->writeCurve(); | ||
|
||
// 绘验证码 | ||
$codeNX = 0; // 验证码第N个字符的左边距 | ||
for ($i = 0; $i < $this->length; $i++) { | ||
$codeNX += mt_rand($this->fontSize * 1.2, $this->fontSize * 1.4); | ||
for ($i = 0; $i < $codeLen; $i++) { | ||
$codeNX += mt_rand($this->conf->fontSize * 1.2, $this->conf->fontSize * 1.4); | ||
// 写一个验证码字符 | ||
imagettftext($this->imInstance, $this->fontSize, mt_rand(-50, 50), $codeNX, (int)($this->fontSize * 1.5), $this->fontColor, $this->useFont, $Code[$i]); | ||
imagettftext($this->imInstance, $this->conf->fontSize, mt_rand(-50, 50), $codeNX, (int)($this->conf->fontSize * 1.5), $this->conf->fontColor, $this->useFont, $code[$i]); | ||
} | ||
|
||
// 输出验证码结果集 | ||
$this->temp = rtrim(str_replace('\\', '/', $this->temp), '/') . '/'; | ||
$this->conf->temp = rtrim(str_replace('\\', '/', $this->conf->temp), '/') . '/'; | ||
mt_srand(); | ||
$func = 'image' . MIME::getExtensionName($this->mime); | ||
$func = 'image' . MIME::getExtensionName($this->conf->mime); | ||
ob_start(); | ||
$func($this->imInstance); | ||
$file = ob_get_contents(); | ||
ob_end_clean(); | ||
imagedestroy($this->imInstance); | ||
return new Result($file, $Code, $this->mime); | ||
return new Result($file, $code, $this->conf->mime); | ||
} | ||
|
||
/** | ||
* 加载字体资源文件 | ||
* @param $fontsPath | ||
* @author : evalor <[email protected]> | ||
* @return array | ||
*/ | ||
private function loadFonts($fontsPath) | ||
|
||
private function loadFonts($fontsPath): array | ||
{ | ||
$dir = dir($fontsPath); | ||
$fonts = []; | ||
|
@@ -106,14 +92,14 @@ private function loadFonts($fontsPath) | |
* 画干扰杂点 | ||
* @author : evalor <[email protected]> | ||
*/ | ||
private function writeNoise() | ||
private function writeNoise(): void | ||
{ | ||
$codeSet = '2345678abcdefhijkmnpqrstuvwxyz'; | ||
for ($i = 0; $i < 10; $i++) { | ||
$noiseColor = imagecolorallocate($this->imInstance, mt_rand(150, 225), mt_rand(150, 225), mt_rand(150, 225)); | ||
for ($j = 0; $j < 5; $j++) { | ||
// 绘杂点 | ||
imagestring($this->imInstance, 5, mt_rand(-10, $this->imageL), mt_rand(-10, $this->imageH), $codeSet[mt_rand(0, 29)], $noiseColor); | ||
imagestring($this->imInstance, 5, mt_rand(-10, (int)$this->conf->imageL), mt_rand(-10, (int)$this->conf->imageH), $codeSet[mt_rand(0, 29)], $noiseColor); | ||
} | ||
} | ||
} | ||
|
@@ -122,56 +108,45 @@ private function writeNoise() | |
* 画干扰曲线 | ||
* @author : evalor <[email protected]> | ||
*/ | ||
private function writeCurve() | ||
private function writeCurve(): void | ||
{ | ||
$px = $py = 0; | ||
// 曲线前部分 | ||
$A = mt_rand(1, $this->imageH / 2); // 振幅 | ||
$b = mt_rand(-$this->imageH / 4, $this->imageH / 4); // Y轴方向偏移量 | ||
$f = mt_rand(-$this->imageH / 4, $this->imageH / 4); // X轴方向偏移量 | ||
$T = mt_rand($this->imageH, $this->imageL * 2); // 周期 | ||
$A = mt_rand(1, $this->conf->imageH / 2); // 振幅 | ||
$b = mt_rand(-$this->conf->imageH / 4, $this->conf->imageH / 4); // Y轴方向偏移量 | ||
$f = mt_rand(-$this->conf->imageH / 4, $this->conf->imageH / 4); // X轴方向偏移量 | ||
$T = mt_rand($this->conf->imageH, $this->conf->imageL * 2); // 周期 | ||
$w = (2 * M_PI) / $T; | ||
$px1 = 0; // 曲线横坐标起始位置 | ||
$px2 = mt_rand($this->imageL / 2, $this->imageL * 0.8); // 曲线横坐标结束位置 | ||
$px2 = mt_rand($this->conf->imageL / 2, $this->conf->imageL * 0.8); // 曲线横坐标结束位置 | ||
for ($px = $px1; $px <= $px2; $px = $px + 1) { | ||
if (0 != $w) { | ||
$py = $A * sin($w * $px + $f) + $b + $this->imageH / 2; // y = Asin(ωx+φ) + b | ||
$i = (int)($this->fontSize / 5); | ||
$py = $A * sin($w * $px + $f) + $b + $this->conf->imageH / 2; // y = Asin(ωx+φ) + b | ||
$i = (int)($this->conf->fontSize / 5); | ||
while ($i > 0) { | ||
// 这里(while)循环画像素点比imagettftext和imagestring用字体大小一次画出(不用这while循环)性能要好很多 | ||
imagesetpixel($this->imInstance, $px + $i, $py + $i, $this->fontColor); | ||
imagesetpixel($this->imInstance, $px + $i, $py + $i, $this->conf->fontColor); | ||
$i--; | ||
} | ||
} | ||
} | ||
// 曲线后部分 | ||
$A = mt_rand(1, $this->imageH / 2); // 振幅 | ||
$f = mt_rand(-$this->imageH / 4, $this->imageH / 4); // X轴方向偏移量 | ||
$T = mt_rand($this->imageH, $this->imageL * 2); // 周期 | ||
$A = mt_rand(1, $this->conf->imageH / 2); // 振幅 | ||
$f = mt_rand(-$this->conf->imageH / 4, $this->conf->imageH / 4); // X轴方向偏移量 | ||
$T = mt_rand($this->conf->imageH, $this->conf->imageL * 2); // 周期 | ||
$w = (2 * M_PI) / $T; | ||
$b = $py - $A * sin($w * $px + $f) - $this->imageH / 2; | ||
$b = $py - $A * sin($w * $px + $f) - $this->conf->imageH / 2; | ||
$px1 = $px2; | ||
$px2 = $this->imageL; | ||
$px2 = $this->conf->imageL; | ||
for ($px = $px1; $px <= $px2; $px = $px + 1) { | ||
if (0 != $w) { | ||
$py = $A * sin($w * $px + $f) + $b + $this->imageH / 2; // y = Asin(ωx+φ) + b | ||
$i = (int)($this->fontSize / 5); | ||
$py = $A * sin($w * $px + $f) + $b + $this->conf->imageH / 2; // y = Asin(ωx+φ) + b | ||
$i = (int)($this->conf->fontSize / 5); | ||
while ($i > 0) { | ||
imagesetpixel($this->imInstance, $px + $i, $py + $i, $this->fontColor); | ||
imagesetpixel($this->imInstance, $px + $i, $py + $i, $this->conf->fontColor); | ||
$i--; | ||
} | ||
} | ||
} | ||
} | ||
|
||
function __get($name) | ||
{ | ||
return $this->conf->$name; | ||
} | ||
|
||
function __set($name, $value) | ||
{ | ||
$this->conf->$name = $value; | ||
} | ||
|
||
} |