证书合成

场景:用户完成培训,根据后台设置的证书模板,给这个人颁发证书

代码

<?php

/**
 * Created by PhpStorm.
 * User: hl
 * Date: 2018/1/23
 * Time: 9:47
 * 证书合成
 */
class  MixCertificate
{
    /** @var  array 用户数据 */
    public $user_info;
    /** @var string 字体 */
    private $font;
    /** @var string 保存文件地址 */
    private $saveDir;
    /** @var string  保存文件地址+文件名 */
    public $savePath;
    /** @var int  Y轴误差 */
    private $Ydeviation = 20;
    /** @var float 字体误差 */
    private $fontSizedeviation;

    /**
     * MixCertificate constructor.
     * @param $user_info array 用户信息
     */
    public function __construct($user_info)
    {

        $this->user_info = $user_info;
        $this->fontSizedeviation = 3 / 4;
        $this->font = ROOT_PATH . '/' . 'static/common/font/msyh.ttc';//微软雅黑
        $this->saveDir = Yii::app()->params['attachmentPath'] . $this->user_info['eid'] . '/certificate/' . date('Y/m');
        $this->savePath = $this->saveDir . '/' . time() . '.png';
    }

    /**
     * AppLication: creatCertificate 合成证书
     * Author: hl
     * @param $certificate_id int 证书id
     * @return bool
     */
    public function creatCertificate($certificate_id)
    {
        $certificateData = Certificat::model()->findByPk($certificate_id);
        if (!$certificateData) return false;
        $certificate_Path = $certificateData->background;
        $sql = 'select m.coordinate_x x,m.coordinate_y y,m.width,m.height,m.content_style,m.type,c.defaults,c.name from {{certificat_module}} m ';
        $sql .= ' left join {{certificat_config}} c on c.id=m.config_id';
        $sql .= ' where m.certificate_id=' . $certificate_id;
        $certificate_Module = Yii::app()->db->createCommand($sql)->queryAll();
        $ModuleData = $this->analysisModule($certificate_Module);
//        var_dump($ModuleData);die;
        /*打开图片*/
        //1.配置图片路径
        $src = ROOT_PATH . '/' . $certificate_Path;
        //2.获取图片信息
        $info = getimagesize($src);
        if (!$info) echo '读取失败';
        //3.通过编号获取图像类型
        $type = image_type_to_extension($info[2], false);
        $fun = "imagecreatefrom" . $type;
        $image = $fun($src);
        //插入文本
        if (isset($ModuleData['text'])) {
            $textArr = $ModuleData['text'];
            foreach ($textArr as $v) {
                $this->insertText($image, $v['defaults'], $v['fontSize'], $v['fontColor'], $v['x'], $v['y'] + $this->Ydeviation, $v['width'], $v['blod']);
            }
        }
        //插入图片
        if (isset($ModuleData['image'])) {
            $textArr = $ModuleData['image'];
            foreach ($textArr as $v) {
                $src2 = ROOT_PATH . '/' . $v['defaults'];
                $info2 = getimagesize($src2);
                if (!$info2) echo '读取失败';
                $type2 = image_type_to_extension($info2[2], false);
                $fun2 = "imagecreatefrom" . $type2;
                $image2 = $fun2($src2);
                if ($v['name'] == 'head_portrait' || $v['name'] == 'logo') {
                    /** 头像做压缩处理 */
                    $image2 = $this->reSetImage($image2, $v['width'], $v['height'], $v['name']);
                }
                $width = imagesx($image2);
                $height = imagesy($image2); //得出图片的高
                imagecopy($image, $image2, $v['x'], $v['y'], 0, 0, $width, $height);
                imagedestroy($image2);
            }
        }
        $fun = "image" . $type;
        $saveDir = $this->saveDir;
        if (!is_dir($saveDir)) mkdir($saveDir, 0777, true);
        imagesavealpha($image, true);
        $fun($image, ROOT_PATH . '/' . $this->savePath);
        /*销毁图片*/
        imagedestroy($image);
        $data = Yii::app()->helping->thumbImages($this->savePath, 1280, [200]);  //生成宽200的缩略图
    }

    /**
     *author hl
     * @param $image //image句柄
     * @param $content //文本内容
     * @param $fontSize //字体大小
     * @param $color //字体颜色
     * @param $Xpostion //字体X轴坐标
     * @param $Ypostion //字体Y轴坐标
     * @param $boxWidth //模块div的宽度
     * @param $boxHeight //模块div的高度
     * @param int $blod //加粗程度
     * 插入文字
     */
    private function insertText($image, $content, $fontSize, $color, $Xpostion, $Ypostion, $boxWidth, $blod = 0)
    {
        $font = $this->font;//font-famlly
        $color = $this->hex2rgb($color);
        $fontSize = $fontSize * $this->fontSizedeviation;//像素和磅的转换
        $img = imagecolorallocatealpha($image, $color['r'], $color['g'], $color['b'], 0);
        $the_box = $this->calculateTextBox($content, $font, $fontSize);
        $Xpostion = $Xpostion + ($boxWidth - $the_box['width']) / 2; //居中处理
        imagettftext($image, $fontSize, 0, $Xpostion, $Ypostion, $img, $font, $content);
        $currentX = $Xpostion;
        for ($i = 0; $i < $blod; $i++) {
            $currentX += 1;
            //字体加粗
            imagettftext($image, $fontSize, 0, $currentX, $Ypostion, $img, $font, $content);
        }
    }

    /**
     * AppLication: hex2rgb 十六进制 转 RGB
     * Author: hl
     * @param $hexColor
     * @return array
     */
    private function hex2rgb($hexColor)
    {
        $color = str_replace('#', '', $hexColor);
        if (strlen($color) > 3) {
            $rgb = array(
                'r' => hexdec(substr($color, 0, 2)),
                'g' => hexdec(substr($color, 2, 2)),
                'b' => hexdec(substr($color, 4, 2))
            );
        } else {
            $color = $hexColor;
            $r = substr($color, 0, 1) . substr($color, 0, 1);
            $g = substr($color, 1, 1) . substr($color, 1, 1);
            $b = substr($color, 2, 1) . substr($color, 2, 1);
            $rgb = array(
                'r' => hexdec($r),
                'g' => hexdec($g),
                'b' => hexdec($b)
            );
        }
        return $rgb;
    }


    /**
     * AppLication: analysisModule 分析证书模块数据
     * Author: hl
     * @param $module
     * @return array|bool [ 'image'=>[],'text'=>[]]
     */
    private function analysisModule($module)
    {
        if (!$module) return false;
        $dataArr = json_decode(CJSON::encode($module), true);
        $res = [];
        foreach ($dataArr as $k => &$v) {
            switch ($v['type']) {
                case 'image':
                    if ($v['name'] == 'head_portrait' || $v['name'] == 'logo') {
                        $temp = $v['defaults'];
                        if ($v['name'] == 'head_portrait') $v['defaults'] = $this->user_info['avatar'] ? $this->user_info['avatar'] : $v['defaults'];
                        if ($v['name'] == 'logo') $v['defaults'] = $this->user_info['logo'] ? $this->user_info['logo'] : $v['defaults'];
                        if (!file_exists(ROOT_PATH . '/' . $v['defaults'])) {
                            $v['defaults'] = $temp;
                        }
                    }
                    $res['image'][] = $v;

                    break;
                case 'text':
                    //非系统填充文本
                    $v['fontSize'] = $this->pregGetfontSize($v['content_style']);
                    $v['fontColor'] = $this->pregGetfontColor($v['content_style']);
                    $v['blod'] = $this->pregGetBold($v['content_style']);
                    $res['text'][] = $v;
                    break;
                case 'system':
                    $v['fontSize'] = $this->pregGetfontSize($v['content_style']);
                    $v['fontColor'] = $this->pregGetfontColor($v['content_style']);
                    $v['blod'] = $this->pregGetBold($v['content_style']);
                    $v['defaults'] = $this->fillingText($v['name']);
                    $res['text'][] = $v;
                    break;
                default:
                    break;
            }
        }
        return $res;
    }

    /**
     * AppLication: fillingText 系统填充文本
     * Author: hl
     * @param $type
     * @return mixed
     */
    private function fillingText($type)
    {
        return $this->user_info[$type];
    }

    /**
     * AppLication: pregGetfontSize 正则匹配font-size
     * Author: hl
     * @param $css
     * @return int
     */
    private function pregGetfontSize($css)
    {
        $pattern = '/font-size:(\d*)px/i';
        $re = preg_match_all($pattern, $css, $arr);
        if ($re && $arr[1]) {
            return $arr[1][0];
        } else {
            return 16;
        }
    }

    /**
     * AppLication: pregGetfontColor 正则匹配color
     * Author: hl
     * @param $css
     * @return string
     */
    private function pregGetfontColor($css)
    {
        $pattern = '/color:(\#\w*)/i';
        $re = preg_match_all($pattern, $css, $arr);
        if ($re && $arr[1]) {
            return $arr[1][0];
        } else {
            return '#000000';
        }
    }

    /**
     * AppLication: pregGetBold 正则匹配bold
     * Author: hl
     * @param $css
     * @return int
     */
    private function pregGetBold($css)
    {
        $pattern = '/bold/i';
        $re = preg_match($pattern, $css, $arr);
        if ($re) return 1;
        return 0;
    }

    /**
     * AppLication: calculateTextBox 算出文本框信息
     * Author: hl
     * @param $text
     * @param $fontFile
     * @param $fontSize
     * @param int $fontAngle
     * @return array
     */
    function calculateTextBox($text, $fontFile, $fontSize, $fontAngle = 0)
    {
        $rect = imagettfbbox($fontSize, $fontAngle, $fontFile, $text);
        $minX = min(array($rect[0], $rect[2], $rect[4], $rect[6]));
        $maxX = max(array($rect[0], $rect[2], $rect[4], $rect[6]));
        $minY = min(array($rect[1], $rect[3], $rect[5], $rect[7]));
        $maxY = max(array($rect[1], $rect[3], $rect[5], $rect[7]));

        return array(
            "left" => abs($minX) - 1,
            "top" => abs($minY) - 1,
            "width" => $maxX - $minX,
            "height" => $maxY - $minY,
            "box" => $rect
        );
    }

    /**
     * AppLication: reSetImage 用户头像缩放处理
     * Author: hl
     * @param $oldImg resource 要处理的图片
     * @param $maxW int   最后确定宽度
     * @param $maxH  int  最后确定高度
     * @param $scene string  场景
     * @return resource
     */
    private function reSetImage($oldImg, $maxW, $maxH, $scene)
    {
        $oldW = imagesx($oldImg);
        $oldH = imagesy($oldImg);
        $newImg = imagecreatetruecolor($maxW, $maxH);
        imagecopyresampled($newImg, $oldImg, 0, 0, 0, 0, $maxW, $maxH, $oldW, $oldH);
        return $newImg;
    }
}

可以转载,但必须说明出处

发表评论