php海报/合同图片生成类

源代码

<?php

/**
 *
 * @authors Your Name (you@example.org)
 * @date    2019-07-18 15:20:32
 * @version $Id$
 */

namespace App\Tools;

class Poster
{

    /**
     * 生成宣传海报
     * @param array  参数,包括图片和文字
     * @param string  $filename 生成海报文件名,不传此参数则不生成文件,直接输出图片
     * @return [type] [description]
     */
    public static function createPoster($config = array(), $filename = "", $ext = 'jpg')
    {
        //如果要看报什么错,可以先注释调这个header
        if (empty($filename)) {
            // header("content-type: image/png");
        }

        $imageDefault = array(
            'left'    => 0,
            'top'     => 0,
            'right'   => 0,
            'bottom'  => 0,
            'width'   => 100,
            'height'  => 100,
            'opacity' => 100,
        );
        $textDefault = array(
            'text'      => '',
            'left'      => 0,
            'top'       => 0,
            'fontSize'  => 32, //字号
            'fontColor' => '255,255,255', //字体颜色
            'angle'     => 0,
        );
        $background = $config['background']; //海报最底层得背景
        //背景方法
        $backgroundInfo   = getimagesize($background);
        $backgroundFun    = 'imagecreatefrom' . image_type_to_extension($backgroundInfo[2], false);
        $background       = $backgroundFun($background);
        $backgroundWidth  = imagesx($background); //背景宽度
        $backgroundHeight = imagesy($background); //背景高度
        $imageRes         = imageCreatetruecolor($backgroundWidth, $backgroundHeight);
        if ($ext == 'png') {
            imagealphablending($imageRes, false);
            imagesavealpha($imageRes, true);
        }
        imagecopyresampled($imageRes, $background, 0, 0, 0, 0, imagesx($background), imagesy($background), imagesx($background), imagesy($background));
        //处理了图片
        if (!empty($config['image'])) {
            foreach ($config['image'] as $key => $val) {
                if ($val && is_array($val) && file_exists($val['url'])) {
                    $val      = array_merge($imageDefault, $val);
                    $info     = getimagesize($val['url']);
                    $function = 'imagecreatefrom' . image_type_to_extension($info[2], false);
                    if ($val['stream']) {
                        //如果传的是字符串图像流
                        $info     = getimagesizefromstring($val['url']);
                        $function = 'imagecreatefromstring';
                    }
                    $res = $function($val['url']);

                    // v($function);

                    $resWidth  = $info[0];
                    $resHeight = $info[1];
                    //建立画板 ,缩放图片至指定尺寸
                    $canvas = imagecreatetruecolor($val['width'], $val['height']);
                    //2.上色   //防止png透明背景变黑 
                    $color = imagecolorallocate($canvas, 255, 255, 255);
                    //3.设置透明 
                    imagecolortransparent($canvas, $color);
                    imagefill($canvas, 0, 0, $color);
                    //设定图像的混色模式
                    imagealphablending($res, true);

                    //关键函数,参数(目标资源,源,目标资源的开始坐标x,y, 源资源的开始坐标x,y,目标资源的宽高w,h,源资源的宽高w,h)
                    imagecopyresampled($canvas, $res, 0, 0, 0, 0, $val['width'], $val['height'], $resWidth, $resHeight);
                    //圆形生成
                    if ($val['is_circular'] == 1) {
                        $canvas = self::markRound($canvas, $val['width'], $val['height']);
                    }
                    $val['left'] = $val['left'] < 0 ? $backgroundWidth - abs($val['left']) - $val['width'] : $val['left'];
                    $val['top']  = $val['top'] < 0 ? $backgroundHeight - abs($val['top']) - $val['height'] : $val['top'];

                    //放置图像
                    imagecopymerge($imageRes, $canvas, $val['left'], $val['top'], $val['right'], $val['bottom'], $val['width'], $val['height'], $val['opacity']); //左,上,右,下,宽度,高度,透明度
                }
            }
        }
        //处理文字
        if (!empty($config['text'])) {
            foreach ($config['text'] as $key => $val) {
                if ($val && is_array($val)) {
                    $val             = array_merge($textDefault, $val);
                    list($R, $G, $B) = explode(',', $val['fontColor']);
                    $fontColor       = imagecolorallocate($imageRes, $R, $G, $B);
                    $val['left']     = $val['left'] < 0 ? $backgroundWidth - abs($val['left']) : $val['left'];
                    $val['top']      = $val['top'] < 0 ? $backgroundHeight - abs($val['top']) : $val['top'];
                    $tmplist         = self::autoLineSplit($val['text'], $val['fontPath'], $val['fontSize'], 'utf8', $val['width']);
                    foreach ($tmplist as $k => $v) {
                        $h = $val['top'] + $k * 30;
                        imagettftext($imageRes, $val['fontSize'], $val['angle'], $val['left'], $h, $fontColor, $val['fontPath'], $v);
                    }
                }
            }
        }
        //生成图片
        if (!empty($filename)) {
            switch ($ext) {
                case 'jpg':
                    $res = imagejpeg($imageRes, $filename, 80); //保存到本地
                    break;
                case 'png':
                    $res = imagepng($imageRes, $filename, 7); //保存到本地
                    break;
            }
            // var_dump($filename);
            imagedestroy($imageRes);
            if (!$res) {
                return false;
            }
            return $filename;
        } else {
            imagejpeg($imageRes); //在浏览器上显示
            imagedestroy($imageRes);
        }
    }

    //生成圆形图片
    public static function markRound($src_img, $w, $h)
    {
        $img = imagecreatetruecolor($w, $h);
        //这一句一定要有
        imagesavealpha($img, true);
        //拾取一个完全透明的颜色,最后一个参数127为全透明
        $bg = imagecolorallocatealpha($img, 59, 105, 138, 127);
        imagefill($img, 0, 0, $bg);
        $r   = $w / 2; //圆半径
        $y_x = $r; //圆心X坐标
        $y_y = $r; //圆心Y坐标
        for ($x = 0; $x < $w; $x++) {
            for ($y = 0; $y < $h; $y++) {
                $rgbColor = imagecolorat($src_img, $x, $y);
                if (((($x - $r) * ($x - $r) + ($y - $r) * ($y - $r)) < ($r * $r))) {
                    imagesetpixel($img, $x, $y, $rgbColor);
                }
            }
        }
        return $img;
    }

    /*
    * 绘图文字分行函数
    * by COoL
    * - 输入:
    * str: 原字符串
    * fontFamily: 字体
    * fontSize: 字号
    * charset: 字符编码
    * width: 限制每行宽度(px)
    * - 输出:
    * 分行后的字符串数组
    */

    public static function autoLineSplit($str, $fontFamily, $fontSize, $charset, $width)
    {
        $result = [];

        $len = (strlen($str) + mb_strlen($str, $charset)) / 2;

        // 计算总占宽
        $dimensions = imagettfbbox($fontSize, 0, $fontFamily, $str);
        $textWidth  = abs($dimensions[4] - $dimensions[0]);

        // 计算每个字符的长度
        $singleW = $textWidth / $len;
        // 计算每行最多容纳多少个字符
        $maxCount = floor($width / $singleW);

        while ($len > $maxCount) {
            // 成功取得一行
            $result[] = mb_strimwidth($str, 0, $maxCount, '', $charset);
            // 移除上一行的字符
            $str = str_replace($result[count($result) - 1], '', $str);
            // 重新计算长度
            $len = (strlen($str) + mb_strlen($str, $charset)) / 2;
        }
        // 最后一行在循环结束时执行
        $result[] = $str;

        return $result;
    }

    /**
     * 制作文本信息数据
     * @param type $param
     */
    public static function toMarkTxt($name, $left = 0, $top = 0, $width = 400, $fontSize = 18, $fontColor = '0,0,0')
    {
        if ($name) {
            $font = base_path() . '/public/upload/app/poster/SourceHanSansCN_Normal.otf';
            $info = [
                'text'      => $name,
                'left'      => $left,
                'top'       => $top,
                'fontSize'  => $fontSize, //字号
                'fontColor' => $fontColor, //字体颜色
                'angle'     => 0,
                'width'     => $width,
                'fontPath'  => $font,
            ];
            return $info;
        }
        return [];
    }

    /**
     * 制作文本信息数据
     * @param type $param
     */
    public static function toMarkImg($imgUrl, $left = 0, $top = 0, $width = 300, $height = 200, $is_circular = 0)
    {
        $info = [
            'url'         => $imgUrl,
            'left'        => $left,
            'top'         => $top,
            'right'       => 0,
            'bottom'      => 0,
            'width'       => $width,
            'height'      => $height,
            'opacity'     => 100,
            'is_circular' => $is_circular,
        ];
        return $info;
    }

    /**
     * 制作货运合同
     */
    public static function markHYHT($orderInfo, $qm1 = '', $qm2 = '')
    {
        # 背景信息
        $config['background'] = base_path() . '/public/upload/app/poster/hyht_1200.jpg';

        $order_sn = $orderInfo['order_sn'];

        $store_name    = $orderInfo['store_name'];
        $user_name     = $orderInfo['car_driver'];
        $goods_name    = $orderInfo['order_name'];
        $start_address = $orderInfo['line_start'] . $orderInfo['start_address'];
        $end_address   = $orderInfo['line_end'] . $orderInfo['end_address'];
        $car_sn        = $orderInfo['car_sn'];
        $car_type      = $orderInfo['car_type'];

        # 文字展示信息
        $nowDate        = date('Y-m-d', time());
        $txt[]          = self::toMarkTxt($store_name, 340, 370); //甲方
        $txt[]          = self::toMarkTxt($user_name, 340, 410, 400); //乙方
        $txt[]          = self::toMarkTxt($store_name, 320, 530); //
        $txt[]          = self::toMarkTxt($goods_name, 180, 570);
        $txt[]          = self::toMarkTxt($goods_name, 300, 650); //货物名
        $txt[]          = self::toMarkTxt('暂无', 765, 650); //货物价值
        $txt[]          = self::toMarkTxt("{$start_address}-{$end_address}", 355, 690, 700, 16); //起运地
        $txt[]          = self::toMarkTxt($car_sn, 280, 730); //车牌号
        $txt[]          = self::toMarkTxt($car_type, 745, 730); //车辆类型
        $txt[]          = self::toMarkTxt($store_name, 300, 1175); //甲方
        $txt[]          = self::toMarkTxt($nowDate, 300, 1220); //甲方日期
        $txt[]          = self::toMarkTxt($user_name, 815, 1175); //甲方
        $txt[]          = self::toMarkTxt($nowDate, 815, 1220); //甲方日期
        $txt            = array_filter($txt);
        $config['text'] = $txt;
        // # 签名展示信息
        // $qm1             = base_path() . '/public/upload/app/poster/qm1.jpg';
        // $qm2             = base_path() . '/public/upload/app/poster/qm2.jpg';
        if ($qm1) {
            $qm1     = base_path() . '/public' . $qm1;
            $image[] = self::toMarkImg($qm1, 180, 1280);
        }
        if ($qm2) {
            $qm2     = base_path() . '/public' . $qm2;
            $image[] = self::toMarkImg($qm2, 710, 1280);
        }
        $config['image'] = $image;
        $filePath        = base_path() . "/storage/app/uploads/poster/contract/{$order_sn}.jpg";
        if (file_exists($filePath)) {
            @unlink($filePath);
        }
        Poster::createPoster($config, $filePath);

        return "/uploads/poster/contract/{$order_sn}.jpg";
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值