用PHP的GD库函数制作优惠券

<?php
class WaterImage  extends Think {//类定义开始
    private   $font='./Public/fonts/msyh.ttf';
    private   $font_alpha='80';
    private   $title_option=array('literal'=>'默认标题水印文字','color'=>'#000000','pos_x'=>100,'pos_y'=>200,'size'=>14,'alpha'=>0,'font'=>'./Public/fonts/msyhbd.ttf');//默认title水印文字配置
    private   $content_option=array('literal'=>'默认正文水印文字','color'=>'#000000','pos_x'=>150,'pos_y'=>200,'size'=>12,'alpha'=>0,'font'=>'./Public/fonts/msyh.ttf');//默认title水印文字配置
    private   $img_option=array('pos_x'=>10,'pos_y'=>10, 'alpha'=>50);//默认水印图片配置
    private   $image='';//中间图
    private   $sourceImage='';//原图
    private   $sInfo='';//原图信息
    private   $waterImg='';//水印图片
    private   $contentLimt=25; //单行文字长度
    private   $contentMax=100; //正文最大文字长度
    private   $percent=1; //水印缩略比例大小
    private   $dateFormat = 'Ymd';
    /**
     * 创建图片
     */
    public function createImg($image){
        $info = $this->getImageInfo($image);
        //建立图像
        $createFun = "imagecreatefrom".$info['type'];
        $image = $createFun($image);
        return $image ;
    }
    /**
     * 设置水印背景图片
     * Enter description here ...
     * @param $sourceImage
     */
    public function setSourceImage($sourceImage){
        $this->sourceImage = $sourceImage;
    }
    /**
     *
     * 总的调用方式
     * @param $data
     */
    public function addWaterMark($sourceImage,$savename='',$imgOpt=array(),$literayOpt=array()){
        if (!file_exists($sourceImage)) throw_exception('源图片不存在,不能添加水印!');
        $this->setSourceImage($sourceImage);
        $this->sInfo = $this->getImageInfo($this->sourceImage);
        $this->image = $this->createImg($this->sourceImage);
        //添加图片水印
        if (!empty($imgOpt)){
            if (isset($imgOpt['waterImg'])){
                $this->waterImg=$imgOpt['waterImg'];
                $waterImgOption=array_merge($this->img_option,$imgOpt['waterOpt']);//后面参数优先级高
                $this->addWaterImg($waterImgOption);//添加图片水印
            }else{
                foreach ($imgOpt as $parameter){
                    $this->waterImg=$parameter['waterImg'];
                    $waterImgOption=array_merge($this->img_option,$parameter['waterOpt']);
                    $this->addWaterImg($waterImgOption);//添加图片水印
                }
            }

        }
        //添加文字水印
        if (!empty($literayOpt)){
            if (isset($literayOpt['titileOpt'])||isset($literayOpt['contentOpt'])) $this->addTitileContent($literayOpt);
            else{
                foreach ($literayOpt as $parameter){
                    $this->addTitileContent($parameter);
                }
            }
        }
        if ($savename!='') {//使用自定义的图片路径和文件名
            $this->saveImg($savename);
        }
        else {
            $attachdir='./Public/Attachment/';        
            $savename=$this->getSaveName();
            $this->saveImg($attachdir.$savename);
        }
        return $savename;
    }

    /**
     +----------------------------------------------------------
     * 为图片添加图片水印
     +----------------------------------------------------------
     +----------------------------------------------------------
     * @param string $source 原文件名
     * @param mixed $water  水印图片array('img'=>'./1.jpg','pos_x'=>10,'pos_y'=>10, 'alpha'=>80)
     +----------------------------------------------------------
     * @return mix
     +----------------------------------------------------------
     * @throws ThinkExecption
     +----------------------------------------------------------
     */
    public function addWaterImg($data) {
        //检查文件是否存在
        if (!file_exists($this->waterImg))
        throw_exception('水印图片不存在!');
        //图片信息
        $wInfo = $this->getImageInfo($this->waterImg);

        //建立图像
        $wImage = $this->createImg($this->waterImg);

        //设定图像的混色模式
        imagealphablending($wImage, true);

        //#图像位置,默认为右下角右对齐,以后调整
        $posY = $data['pos_y'];
        $posX =$data['pos_x'];

        //对水印图片缩略
        if (!isset($data['newwidth'])&&!isset($data['newheight'])){//长宽都没设置,则按百分比
            $data['newwidth'] = $wInfo["width"] * $this->percent;
            $data['newheight'] = $wInfo['height']* $this->percent;
        }elseif (!isset($data['newwidth'])){//没设置宽,则按长为准
              $this->percent=$wInfo["width"] / $wInfo['height'];//宽长比              
               $data['newwidth'] =  round($data['newheight'] * $this->percent,2);
           
        }elseif (!isset($data['newheight'])) {//没设置长,则按宽为准
            $this->percent=$wInfo['height']/$wInfo["width"];//宽长比        
            $data['newheight'] = round($data['newwidth'] * $this->percent,2);
        }
        $thumb = imagecreatetruecolor( $data['newwidth'], $data['newheight']);
        $wImage = $this->createImg($this->waterImg);
        // Resize
        imagecopyresized($thumb, $wImage, 0, 0, 0, 0,  $data['newwidth'], $data['newheight'], $wInfo["width"],$wInfo['height']);
        //生成混合图像,这是生成图片水印最关键的
        imagecopymerge($this->image, $thumb, $posX, $posY, 0, 0,  $data['newwidth'], $data['newheight'], $data['alpha']);
        imagedestroy($thumb);
        return $this->image;
    }
    /**
     * 分别给文字标题和内容加水印
     *  @param $data
        array(
        'titileOpt'=>array('literal'=>'默认水印文字'),
        'contentOpt'=>array(...)
        )
     */
    public function addTitileContent($data){
        if (empty($data)) return ;
        if (isset($data['titileOpt'])){
            $titileOpt=array_merge($this->title_option,$data['titileOpt']);
            $this->addWaterText($titileOpt);
        }
        if (isset($data['contentOpt'])){
            $contentOpt=array_merge($this->content_option,$data['contentOpt']);
            $literalen=mb_strlen(trim($contentOpt['literal']),'utf-8');//获取文字长度
            if ($literalen>$this->contentLimt){//文字水印超过了单行限制
                if ($literalen>$this->contentMax) throw_exception('正文内容超过了最大文字长度限制:'.$this->contentMax);
                $literal=$this->phaseContent(trim($contentOpt['literal']));

                foreach ($literal as $i=>$tring){
                    $contentOpt['literal']=$tring;
                    if ($i==0)     $this->addWaterText($contentOpt);
                    else{
                        $contentOpt['pos_y']+=20;
                        $this->addWaterText($contentOpt);
                    }
                }
            }else $this->addWaterText($contentOpt);
        }

    }
    /**
     *
     * 分割字符串为数组
     * @param unknown_type $string
     */
    public function phaseContent($string){
        import("ORG.Util.String");
        $data=array();
        $string_arr=explode("\n", $string);//必须用双引号
        foreach ($string_arr as $value){
            $lenth=mb_strlen(trim($value),'utf-8');
            if($lenth>$this->contentLimt){
                for ($i=0;$i<$lenth;$i+=$this->contentLimt){
                    $temp=String::msubstr(trim($value), $i, $this->contentLimt,'utf-8',false);
                    array_push($data, $temp);
                }
                continue;
            }
            array_push($data, $value);
        }    
        if (count($data)>4) array_splice($data, 4);
        return $data;
    }
    /**
     *
     *给图片添加文字
     *文字水印
     *@param array $data array(array('literal'=>'literal','color'=>'mixed','pos_x'=>10,'pos_y'=>10,'size'=>14,'alpha'=>80,'font'=>'mysh.ttf'))
     */
    function addWaterText($data){
        $c = $this->_parseColor($data['color']);
        $data['color'] = imagecolorallocatealpha($this->image, $c[0], $c[1], $c[2], $data['alpha']);
        imagettftext($this->image,$data['size'], 0, $data['pos_x'], $data['pos_y'], $data['color'], $data['font'],$data['literal']);
        return $this->image;
    }
    /**
     *
     * @param unknown_type $sourceImage 源图像路径
     * @param unknown_type $sImage    通过函数产生的图像
     * @param $savename 存储路径
     */
    function saveImg($savename){
        //输出图像
        $ImageFun = 'Image' . $this->sInfo['type'];
        //如果没有给出保存文件名,默认为原图像名
        if (!$savename) {
            $savename = $this->sourceImage;
            @unlink($this->sourceImage);
        }
        //保存图像
        $ImageFun($this->image, $savename);
        imagedestroy($this->image);
    }
    /**
     +----------------------------------------------------------
     * 取得图像信息
     *
     +----------------------------------------------------------
     * @static
     * @access public
     +----------------------------------------------------------
     * @param string $image 图像文件名
     +----------------------------------------------------------
     * @return mixed
     +----------------------------------------------------------
     */
    function getImageInfo($img) {
        $imageInfo = getimagesize($img);
        if ($imageInfo !== false) {
            $imageType = strtolower(substr(image_type_to_extension($imageInfo[2]), 1));
            $imageSize = filesize($img);
            $info = array(
                "width" => $imageInfo[0],
                "height" => $imageInfo[1],
                "type" => $imageType,
                "size" => $imageSize,
                "mime" => $imageInfo['mime']
            );
            return $info;
        } else {
            return false;
        }
    }

    /**
     * 分析颜色
     *
     * @param    string     $color    十六进制颜色
     */
    private function _parseColor($color)
    {
        $arr = array();
        for($ii=1; $ii<strlen($color); $ii++)
        {
            $arr[] = hexdec(substr($color,$ii,2));
            $ii++;
        }

        Return $arr;
    }
    private   function getSaveName() {
        $md5=md5(mktime().rand());
        $name=substr($md5, 0,13);
        $saveName=$name.'.'.$this->sInfo['type'];
        $saveName = $this->getDirName().'/'.$saveName;
        return $saveName;
    }
    /**
     +----------------------------------------------------------
     * 获取子目录的名称
     */
    private function getDirName() {
        $attachdir='./Public/Attachment/';
        $dir   =  date($this->dateFormat,time());
        if(!is_dir($attachdir.$dir)) {
            mk_dir($attachdir.$dir);
        }
        return $dir;
    }
}

写的过程还是比较简单的,主要注意字体路径要对,图片路径必须是绝对路径,从磁盘开始的。

放在TP框架里面的,可以独立拿出来使用,优惠券的字断行不好处理。

使用案例:

                $water=APP_PATH .'/Public/images/homelogo.jpg';    //水印图
                $active='./Public/Attachment/'.$_POST['activeimg'];
                if (!file_exists($active)) throw_exception('商家上传图片不存在,不能添加水印!');
                $watermark=new WaterImage();
                $timest = strtotime("+".$_POST['validaynum']." days",time());  // 30天后的时间戳
                $date=date("Y-m-d",$timest);   // 格式化日期
                //设置具体图片参数
                $imgOpt[]=array('waterImg'=>$water,'waterOpt'=>array('pos_x'=>0,'pos_y'=>0, 'alpha'=>80));//添加logo
                $imgOpt[]=array('waterImg'=>$active,'waterOpt'=>array('pos_x'=>120,'pos_y'=>160, 'alpha'=>80,'newwidth'=>280,'newheight'=>170));//添加中间的活动图片
                $literayOpt=array(//文字水印参数,可以为一维数组,可选
                array(
                   'titileOpt'=>array('literal'=>'详       情:','pos_x'=>40,'pos_y'=>380,'size'=>12),
                   'contentOpt'=>array('literal'=>$_POST['Details'],'pos_x'=>120,'pos_y'=>380,'size'=>10)
                ),
                array(
                   'titileOpt'=>array('literal'=>'店       名:','pos_x'=>40,'pos_y'=>455,'size'=>12),
                   'contentOpt'=>array('literal'=>$refectoryInfo['refectory_name'],'pos_x'=>120,'pos_y'=>455,'size'=>10)
                ),
                array(
                 'titileOpt'=>array('literal'=>'地       址:','pos_x'=>40,'pos_y'=>480,'size'=>12),
                 'contentOpt'=>array('literal'=>$refectoryInfo['refectory_address'],'pos_x'=>120,'pos_y'=>480,'size'=>10)
                ),
                array(
                 'titileOpt'=>array('literal'=>'电       话:','pos_x'=>40,'pos_y'=>505,'size'=>12),
                 'contentOpt'=>array('literal'=>$refectoryInfo['bespeak_meal'],'pos_x'=>120,'pos_y'=>505,'size'=>10)
                ),
                array(
                 'titileOpt'=>array('literal'=>'有效期至:','pos_x'=>40,'pos_y'=>530,'size'=>12),
                 'contentOpt'=>array('literal'=>$date,'pos_x'=>120,'pos_y'=>530,'size'=>10)
                )
                );
                if ($_POST['type_coupon']==2){
                    $literayOpt[]=array(
                        'contentOpt'=>array('literal'=>$_POST['discount'].' 折优惠','pos_x'=>150,'pos_y'=>120,'size'=>40,'color'=>'#CB1B0D','font'=>'./Public/fonts/STXINGKA.TTF')
                    );
                }
                if ($_POST['type_coupon']==1){
                    $literayOpt[]=array(
                        'contentOpt'=>array('literal'=>'立减 '.$_POST['discount'].'元','pos_x'=>150,'pos_y'=>120,'size'=>40,'color'=>'#CB1B0D','font'=>'./Public/fonts/STXINGKA.TTF')
                    );
                }
             //添加水印
             $watername =$watermark->addWaterMark($imgTemplate,'',$imgOpt,$literayOpt);
原文地址:https://www.cnblogs.com/steptoupper/p/2862624.html