1.话不多说,直接干货,喜欢的希望大家一键三连

<?php


namespace App\Model;


class VerifyImage
{
    //浮层坐标数组
    protected $tailoringArray = [];
    //浮层图宽
    protected $picW = 100;
    //浮层图高
    protected $picH = 100;
    //浮层图圆半径
    protected $r = 10;

    //截图小图路径
    protected $tailoringSmallSavePath;
    //截图大图路径
    protected $tailoringBigSavePath;

    //截图小图图片名称
    protected $tailoringSmallName;
    //截图大图图片名称
    protected $tailoringBigName;

    //图片后缀
    protected $picSuffix = '.png';

    //原图路径
    protected $srcPic;
    //原图信息
    protected $picInfo;

    //图片保存路径
    protected $picSavePath;
    //资源图片路径
    protected $resourcesPath;


    //初始化相关数据
    public function init()
    {
        $this->resourcesPath = BASE_PATH . '/static/code/';
        //背景图片存放目录 (Resources)
        $dir = BASE_PATH . '/static/images/code/' . date('YmdH');
        //被处理图片 存放目录(裁剪小图,错位背景图)
        $this->tailoringBigSavePath = $dir . '/big/';
        $this->tailoringSmallSavePath = $dir . '/small/';
        $this->getRandomPng();
        $this->tailoringSmallName = $this->tailoringSmallSavePath . md5(uniqid()) . $this->picSuffix;
        $this->tailoringBigName = $this->tailoringBigSavePath . md5(uniqid() . time()) . $this->picSuffix;
        //检查目录是否存在
        if (!file_exists($this->tailoringBigSavePath)) {
            mkdir($this->tailoringBigSavePath, 0777, true);
        }
        if (!file_exists($this->tailoringSmallSavePath)) {
            mkdir($this->tailoringSmallSavePath, 0777, true);
        }
        //删除过时资源图片
        $this->picSavePath = dirname($dir);
        //删除一小时之前图片
        $this->deleteHourXSVerificationImage($this->picSavePath);
    }


    public function __construct()
    {
        $this->init();
        //  获取原图的 宽高
        $this->picInfo = $this->getPicWidthHeight($this->srcPic);
        $this->getTailoringImage();
    }

    // 获取图片宽、高
    public function getPicWidthHeight($pic_path)
    {
        $lim_size = getimagesize($pic_path);
        return array('w' => $lim_size[0], 'h' => $lim_size[1]);
    }

    //随机获取参照图片
    private function getRandomPng()
    {
        $this->srcPic = $this->resourcesPath . $this->tailoringBigName . mt_rand(1, 4) . '.png';

        echo $this->srcPic;
        if (!file_exists($this->srcPic)) {
            throw new \Exception('图片资源不存在!!!');
        } else {
            return $this->srcPic;
        }
    }

    //获取浮层图片
    public function getTailoringImage(){

        $dr = $this->r*$this->r;    //半径平方
        $local_w = $this->r*2-5;
        //第一个圆中心点
        $circular1_x = $local_w+($this->picW-($local_w)*2)/2;
        $circular1_y = $this->r;
        //第二个圆中心点
        $circular2_x = $this->picH-$this->r;
        $circular2_y = $local_w+($this->picH-($local_w)*2)/2;;

        for($i=0;$i<$this->picH;$i++){
            for($j=0;$j<$this->picW;$j++){
                //根据公式(x-a)²+(y-b)² = r² 算出像素是否在圆内
                $d1 = pow($j-$circular1_x,2)+pow($i-$circular1_y,2);
                $d2 = pow($j-$circular2_x,2)+pow($i-$circular2_y,2);

                if(($i>=$local_w && $j>=$local_w && $i<=$this->picH-$local_w && $j<=$this->picW-$local_w) || $d1<=$dr || $d2<=$dr){
                    $this->tailoringArray[$i][$j] = 1;   //在拼图内为1
                } else {
                    $this->tailoringArray[$i][$j] = 0;   //在拼图外为0
                }
            }
        }
    }

    // 创建背景图和浮层图、浮层图x,y坐标
    public function createImage(){
        //原图
        $srcFile = $this->srcPic;
        $src_w   = $this->picInfo['w'];    //原图宽
        $src_h   = $this->picInfo['h'];    //原图高
        $src_im  = imagecreatefrompng($srcFile);

        $dst_im = imagecreatetruecolor($src_w,$src_h);
        //根据原图尺寸创建一个相同大小的真彩色位图
        //给新图填充背景色
        $black = imagecolorallocate($dst_im,0,0,0);//
        imagefill($dst_im,0,0,$black);
        imagecopymerge($dst_im,$src_im,0,0,0,0,$src_w,$src_h,100);//原图图像写入新建真彩位图中

        //生成透明底拼图画布
        $jigsaw_im = imagecreatetruecolor($this->picW,$this->picH);   //100*100拼图画布
        imagealphablending($jigsaw_im,false);
        imagesavealpha($jigsaw_im, true);
        $jigsaw_bg = imagecolorallocatealpha($jigsaw_im,0,0,0,127);
        imagefill($jigsaw_im, 0, 0, $jigsaw_bg);

        //随机位置
        $src_x = mt_rand(215,$src_w-$this->picW); //水印位于大图x坐标
        $src_y= mt_rand(0,$src_h-35); //y坐标

        $this->rgb_white = imagecolorallocatealpha($dst_im,127,127,127,60);   //灰色水印
        //循环轮廓抠图
        for($i=0;$i<$this->picH;$i++){
            for ($j=0;$j<$this->picW;$j++){
                if($this->tailoringArray[$i][$j] == 1){
                    //如果在轮廓内,取原图像素颜色
                    $this->rgb = ImageColorAt($dst_im,$src_x+$j,$src_y+$i);
                    imagesetpixel($jigsaw_im,$j,$i,$this->rgb);   //在拼图画布上色
                    //在原图挖坑(打上灰色)
                    imagesetpixel($dst_im,$src_x+$j,$src_y+$i,$this->rgb_white);
                }
            }
        }

        //保存图片
        imagepng($dst_im,$this->tailoringBigName);
        imagepng($jigsaw_im,$this->tailoringSmallName);
        imagedestroy($src_im);
        imagedestroy($dst_im);
        imagedestroy($jigsaw_im);

        return ['tailoringBgImage'=>$this->tailoringBigName,'tailoringImage'=>$this->tailoringSmallName,'x'=>$src_x,'y'=>$src_y];
    }

    // 删除一小时之前的 验证码图片
    public function deleteHourXSVerificationImage($dir)
    {
        $op = dir($dir);
        $time = date("YmdH", strtotime("-1 hours"));
        $i = 0;
        while (false != ($item = $op->read()) && $i <= 10) {
            $i++;
            if ($item == '.' || $item == '..') {
                continue;
            }
            if (is_numeric($item) && $item <= $time || !is_numeric($item)) {
                if (is_dir($op->path . '/' . $item) && rmdir($op->path . '/' . $item) == false) {
                    $this->deleteHourXSVerificationImage($op->path . '/' . $item);
                } else {
                    echo $op->path . '/' . $item;
                    unlink($op->path . '/' . $item);
                }
            }
        }
    }

}

 

版权声明:本文为sir_zhang原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/death-/p/16991973.html