图片验证码

本实例主要是为了解决部分用户输出验证码的时候,未能正确的把验证码响应至HTTP响应的问题。

namespace  App\Utility\VerifyCode;

class Verify
{
    public static function create($codeStr){
        $codeSet = '12346789ABCDEFGHJKLMNPQRTUVWXY';//字符容器
        $fontSize = 25;     // 验证码字体大小(px)
        $useCurve = true;   // 是否画混淆曲线
        $useNoise = true;   // 是否添加杂点
        $imageH = 0;        // 验证码图片宽
        $imageL = 0;        // 验证码图片长
        $length = 4;        // 验证码位数
        $bg = array(243, 251, 254);  // 背景
        $_image = null;     // 验证码图片实例
        $_color = null;     // 验证码字体颜色
        $imageL = $length * $fontSize * 1.5 + $fontSize*1.5;
        $imageH = $fontSize * 2;
        // 建立一幅图像
        $_image = imagecreate($imageL,$imageH);
        // 设置背景
        imagecolorallocate($_image,$bg[0], $bg[1], $bg[2]);
        // 验证码字体随机颜色
        $_color = imagecolorallocate($_image, mt_rand(1,120), mt_rand(1,120), mt_rand(1,120));
        // 验证码使用随机字体   暂时不做
        $ttf = __DIR__.'/'."font.ttf";
        /**
         * 画杂点
         * 往图片上写不同颜色的字母或数字
         */
        for($i = 0; $i < 10; $i++){
            //杂点颜色
            $noiseColor = imagecolorallocate(
                $_image,
                mt_rand(150,225),
                mt_rand(150,225),
                mt_rand(150,225)
            );
            for($j = 0; $j < 5; $j++){
                // 绘杂点
                imagestring(
                    $_image,
                    5,
                    mt_rand(-10, $imageL),
                    mt_rand(-10, $imageH),
                    $codeSet[mt_rand(0, 27)], // 杂点文本为随机的字母或数字
                    $noiseColor
                );
            }
        }
        //画出横穿干扰线
        $A = mt_rand(1, $imageH/2);                  // 振幅
        $b = mt_rand(-$imageH/4,$imageH/4);   // Y轴方向偏移量
        $f = mt_rand(-$imageH/4,$imageH/4);   // X轴方向偏移量
        $T = mt_rand($imageH*1.5, $imageL*2);  // 周期
        $w = (2* M_PI)/$T;
        $px1 = 0;  // 曲线横坐标起始位置
        $px2 = mt_rand($imageL/2,$imageL * 0.667);  // 曲线横坐标结束位置
        for ($px=$px1; $px<=$px2; $px=$px+ 0.9) {
            if ($w!=0) {
                $py = $A * sin($w*$px + $f)+ $b + $imageH/2;  // y = Asin(ωx+φ) + b
                $i = (int) (($fontSize - 6)/4);
                while ($i > 0) {
                    imagesetpixel($_image, $px + $i, $py + $i, $_color);  // 这里画像素点比imagettftext和imagestring性能要好很多
                    $i--;
                }
            }
        }

        $A = mt_rand(1,$imageH/2);                  // 振幅
        $f = mt_rand(-$imageH/4, $imageH/4);   // X轴方向偏移量
        $T = mt_rand($imageH*1.5, $imageL*2);  // 周期
        $w = (2* M_PI)/$T;
        $b = $py - $A * sin($w*$px + $f) - $imageH/2;
        $px1 = $px2;
        $px2 = $imageL;
        for ($px=$px1; $px<=$px2; $px=$px+ 0.9) {
            if ($w!=0) {
                $py = $A * sin($w*$px + $f)+ $b + $imageH/2;  // y = Asin(ωx+φ) + b
                $i = (int) (($fontSize - 8)/4);
                while ($i > 0) {
                    imagesetpixel($_image, $px + $i, $py + $i, $_color);  // 这里(while)循环画像素点比imagettftext和imagestring用字体大小一次画出(不用这while循环)性能要好很多
                    $i--;
                }
            }
        }
        //将验证码写入
        // 绘验证码
        if(!empty($codeStr)){
            $codeNX = 0; // 验证码第N个字符的左边距
            for ($i = 0; $i<$length; $i++) {
                $codeNX += mt_rand($fontSize*1.2,$fontSize*1.6);
                // 写一个验证码字符
                imagettftext($_image,$fontSize, mt_rand(-40, 70), $codeNX, $fontSize*1.5, $_color, $ttf, $codeStr[$i]);
            }
        }
        ob_start();
        imagepng($_image);
        $image = ob_get_contents();
        ob_end_clean();
        imagedestroy($_image);
        return new Result($codeStr,$image);
    }
}

关键点在于ob_start与ob_end_clean,原因在于imagepng 其实是等于 echo $var;这样无法把图片信息响应到response中。

namespace App\Utility\VerifyCode;

class Result
{
    protected $codeStr;
    protected $imageSting;
    protected $imageMineType = 'image/png';
    function __construct($string,$image)
    {
        $this->codeStr = $string;
        $this->imageSting = $image;
    }

    /**
     * @return mixed
     */
    public function getCodeStr()
    {
        return $this->codeStr;
    }

    /**
     * @return mixed
     */
    public function getImageSting()
    {
        return $this->imageSting;
    }

    /**
     * @return string
     */
    public function getImageMineType()
    {
        return $this->imageMineType;
    }

}

注意,生成验证码的时候,需要字体文件。本代码对应的字体文件是verify_code_font.ttf

results matching ""

    No results matching ""