ThinkPHP 水印文字换行及居中

问题需求:
1、文字超出图片大小换行
2、最后一行文字居中显示
thinkphp生成的文字水印只显示一行,需要修改图片处理类

第一步,修改 ThinkPHP\Library\Think\ Image.class.php

修改内容如下:
1、添加 $txt_width 背景图片宽度

/**
     * 图像添加文字
     * @param  string  $text   添加的文字
     * @param  string  $font   字体路径
     * @param  integer $size   字号
     * @param  string  $color  文字颜色
     * @param  integer $locate 文字写入位置
     * @param  integer $offset 文字相对当前位置的偏移量
     * @param  integer $angle  文字倾斜角度
     * @param  integer $txt_width  背景图片宽度
     * @return Object          当前图片处理库对象
     */
    public function text($text, $font, $size, $color = '#00000000', 
        $locate = self::IMAGE_WATER_SOUTHEAST, $offset = 0, $angle = 0,$txt_width = null){
        $this->img->text($text, $font, $size, $color, $locate, $offset, $angle,$txt_width);
        return $this;
    }

第二步,GD库为例 修改 ThinkPHP\Library\Think\Image\Driver\Gd.class.php

1、添加换行标记

if($txt_width){
    $txt_max_width = intval(0.8*$txt_width);
    $text = "";
    for ($i=0;$i<mb_strlen($come);$i++) {
        $letter[] = mb_substr($come, $i, 1);
    }
    foreach ($letter as $l) {
        $teststr = $text." ".$l;
        $testbox = imagettfbbox($size,$angle,$font,$teststr);
        // 判断拼接后的字符串是否超过预设的宽度。超出宽度添加换行
        if (($testbox[2] > $txt_max_width) && ($text !== "")) {
            $text .= "\n";
        }
        $text .= $l;
    }
}

2、改写文字输出坐标

【这个功能分两种情况!!!!!】

(1)位置最后一行不居中

if($txt_width){
    $width = $testbox[2]-$testbox[0];
    $x = ($txt_width - $width) / 2; //文字居中
}
imagettftext($this->img, $size, $angle, $x + $ox, $y + $oy, $col, $font, $text);

(2)位置最后一行居中

foreach ($text as $key => $value) {//最后一行居中
    $textbox = imagettfbbox($size, $angle, $font,$value);
    $txt_height = $textbox[0]-$textbox[7];
    $text_width = $textbox[2]-$textbox[0];
    if($txt_width){
        $x = ($txt_width - $text_width) / 2; //文字居中
    }
    imagettftext($this->img, $size, $angle, $x + $ox, $y + $oy, $col, $font, $value);
    $y = $y+$txt_height+9; // 加9为调整行距
}

整体代码如下:

/**
     * 图像添加文字
     * @param  string  $text   添加的文字
     * @param  string  $font   字体路径
     * @param  integer $size   字号
     * @param  string  $color  文字颜色
     * @param  integer $locate 文字写入位置
     * @param  integer $offset 文字相对当前位置的偏移量
     * @param  integer $angle  文字倾斜角度
     */
    public function text($come, $font, $size, $color = '#00000000',
                         $locate = Image::IMAGE_WATER_SOUTHEAST, $offset = 0, $angle = 0,$txt_width = null){
        if($txt_width){
            $txt_max_width = intval(0.8*$txt_width);
            $text = "";
            for ($i=0;$i<mb_strlen($come);$i++) {
                $letter[] = mb_substr($come, $i, 1);
            }
            foreach ($letter as $l) {
                $teststr = $text." ".$l;
                $testbox = imagettfbbox($size,$angle,$font,$teststr);
                // 判断拼接后的字符串是否超过预设的宽度。超出宽度添加换行
                if (($testbox[2] > $txt_max_width) && ($text !== "")) {
                    $text .= "\n";
                }
                $text .= $l;
            }
        }
        $text = explode("\n",$text?$text:$come);

        //资源检测
        if(empty($this->img)) E('没有可以被写入文字的图像资源');
        if(!is_file($font)) E("不存在的字体文件:{$font}");

        //获取文字信息
        $info = imagettfbbox($size, $angle, $font, $text);
        $minx = min($info[0], $info[2], $info[4], $info[6]);
        $maxx = max($info[0], $info[2], $info[4], $info[6]);
        $miny = min($info[1], $info[3], $info[5], $info[7]);
        $maxy = max($info[1], $info[3], $info[5], $info[7]);

        /* 计算文字初始坐标和尺寸 */
        $x = $minx;
        $y = abs($miny);
        $w = $maxx - $minx;
        $h = $maxy - $miny;

        /* 设定文字位置 */
        switch ($locate) {
            /* 右下角文字 */
            case Image::IMAGE_WATER_SOUTHEAST:
                $x += $this->info['width']  - $w;
                $y += $this->info['height'] - $h;
                break;

            /* 左下角文字 */
            case Image::IMAGE_WATER_SOUTHWEST:
                $y += $this->info['height'] - $h;
                break;

            /* 左上角文字 */
            case Image::IMAGE_WATER_NORTHWEST:
                // 起始坐标即为左上角坐标,无需调整
                break;

            /* 右上角文字 */
            case Image::IMAGE_WATER_NORTHEAST:
                $x += $this->info['width'] - $w;
                break;

            /* 居中文字 */
            case Image::IMAGE_WATER_CENTER:
                $x += ($this->info['width']  - $w)/2;
                $y += ($this->info['height'] - $h)/2;
                break;

            /* 下居中文字 */
            case Image::IMAGE_WATER_SOUTH:
                $x += ($this->info['width'] - $w)/2;
                $y += $this->info['height'] - $h;
                break;

            /* 右居中文字 */
            case Image::IMAGE_WATER_EAST:
                $x += $this->info['width'] - $w;
                $y += ($this->info['height'] - $h)/2;
                break;

            /* 上居中文字 */
            case Image::IMAGE_WATER_NORTH:
                $x += ($this->info['width'] - $w)/2;
                break;

            /* 左居中文字 */
            case Image::IMAGE_WATER_WEST:
                $y += ($this->info['height'] - $h)/2;
                break;

            default:
                /* 自定义文字坐标 */
                if(is_array($locate)){
                    list($posx, $posy) = $locate;
                    $x += $posx;
                    $y += $posy;
                } else {
                    E('不支持的文字位置类型');
                }
        }

        /* 设置偏移量 */
        if(is_array($offset)){
            $offset = array_map('intval', $offset);
            list($ox, $oy) = $offset;
        } else{
            $offset = intval($offset);
            $ox = $oy = $offset;
        }

        /* 设置颜色 */
        if(is_string($color) && 0 === strpos($color, '#')){
            $color = str_split(substr($color, 1), 2);
            $color = array_map('hexdec', $color);
            if(empty($color[3]) || $color[3] > 127){
                $color[3] = 0;
            }
        } elseif (!is_array($color)) {
            E('错误的颜色值');
        }

        do{
            /* 写入文字 */
            $col = imagecolorallocatealpha($this->img, $color[0], $color[1], $color[2], $color[3]);
            //最后一行不居中
            /*if($txt_width){
                $width = $testbox[2]-$testbox[0];
                $x = ($txt_width - $width) / 2; //文字居中
            }
            imagettftext($this->img, $size, $angle, $x + $ox, $y + $oy, $col, $font, $text);
            */
            foreach ($text as $key => $value) {//最后一行居中
                $textbox = imagettfbbox($size, $angle, $font,$value);
                $txt_height = $textbox[0]-$textbox[7];
                $text_width = $textbox[2]-$textbox[0];
                if($txt_width){
                    $x = ($txt_width - $text_width) / 2; //文字居中
                }
                imagettftext($this->img, $size, $angle, $x + $ox, $y + $oy, $col, $font, $value);
                $y = $y+$txt_height+9; // 加4为调整行距
            }
        } while(!empty($this->gif) && $this->gifNext());
    }

调用实例

private function QrCode($url, $level, $size, $file,$text)
    {
        vendor('Qrcode.phpqrcode');
        $qrcode = new \QRcode();
        $qrcode->png($url, $file, $level, $size, 2);

        $image = new \Think\Image();
        $logo = self::PATH_ELEVATOR.'key/logo.png';
        $image->open($file)->thumb(300, 300)->water($logo,5,100)->save($file);
        //写入文字
        $size = 16;
        $background = self::PATH_ELEVATOR.'key/background.png';
        $font = self::PATH_ELEVATOR.'key/1.ttf';
        $image->open($background)->water($file,array(150,457),100)->text($text,$font,$size,'#ffffff',array(50,826),0,0,600)->save($file);
        return file_exists($file) ? $file : false;
    }

效果图:

(1)文字不居中
这里写图片描述
(2)文字居中
这里写图片描述

猜你喜欢

转载自blog.csdn.net/qq_16024861/article/details/81508788