Graent.Hu 的博客

新浪微薄腾讯微薄

最新碎语:最近感觉有些迷茫,怎么办~

您的位置:Graent.Hu 的博客 >PHP编程> thinkPHP5图片加文字水印实现换行的方法

thinkPHP5图片加文字水印实现换行的方法

原有的添加文字的代码:


Image::open(ROOT_PATH . "1.jpg")
            ->text("斯巴奴男装狐狸毛领中长款加厚asdasdsadasdasdasdasdasdasdasdsad白鸭绒","./template/common/fonts/yahei.ttf",20,"#000000",[5,5])
            ->save(ROOT_PATH . "2.jpg",null,100);
        echo "<img src='/2.jpg'>";
在原来的Image类的基础上使用上面的代码得到的生成结果是这样的:


TIM截图20181017192604.jpg

文字显示在一行,超出悲剧图片的大小右边没有显示完全,所以对Image类进行修改,实现无需手动添加换行符(“\n”)也能自动换行,在ThinkPHP项目找到\vendor\topthink\think-image\src\Image.php文件,大约在470行之下,原代码:


/**
     * 图像添加文字
     *
     * @param  string  $text   添加的文字
     * @param  string  $font   字体路径
     * @param  integer $size   字号
     * @param  string  $color  文字颜色
     * @param int      $locate 文字写入位置
     * @param  integer $offset 文字相对当前位置的偏移量
     * @param  integer $angle  文字倾斜角度
     *
     * @return $this
     * @throws ImageException
     */
    public function text($text, $font, $size, $color = '#00000000',
        $locate = self::WATER_SOUTHEAST, $offset = 0, $angle = 0) {

        if (!is_file($font)) {
            throw new ImageException("不存在的字体文件:{$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 self::WATER_SOUTHEAST:
                $x += $this->info['width'] - $w;
                $y += $this->info['height'] - $h;
                break;
            /* 左下角文字 */
            case self::WATER_SOUTHWEST:
                $y += $this->info['height'] - $h;
                break;
            /* 左上角文字 */
            case self::WATER_NORTHWEST:
                // 起始坐标即为左上角坐标,无需调整
                break;
            /* 右上角文字 */
            case self::WATER_NORTHEAST:
                $x += $this->info['width'] - $w;
                break;
            /* 居中文字 */
            case self::WATER_CENTER:
                $x += ($this->info['width'] - $w) / 2;
                $y += ($this->info['height'] - $h) / 2;
                break;
            /* 下居中文字 */
            case self::WATER_SOUTH:
                $x += ($this->info['width'] - $w) / 2;
                $y += $this->info['height'] - $h;
                break;
            /* 右居中文字 */
            case self::WATER_EAST:
                $x += $this->info['width'] - $w;
                $y += ($this->info['height'] - $h) / 2;
                break;
            /* 上居中文字 */
            case self::WATER_NORTH:
                $x += ($this->info['width'] - $w) / 2;
                break;
            /* 左居中文字 */
            case self::WATER_WEST:
                $y += ($this->info['height'] - $h) / 2;
                break;
            default:
                /* 自定义文字坐标 */
                if (is_array($locate)) {
                    list($posx, $posy) = $locate;
                    $x += $posx;
                    $y += $posy;
                } else {
                    throw new ImageException('不支持的文字位置类型');
                }
        }
        /* 设置偏移量 */
        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)) {
            throw new ImageException('错误的颜色值');
        }
        do {
            /* 写入文字 */
            $col = imagecolorallocatealpha($this->im, $color[0], $color[1], $color[2], $color[3]);
            imagettftext($this->im, $size, $angle, $x + $ox, $y + $oy, $col, $font, $text);
        } while (!empty($this->gif) && $this->gifNext());
        return $this;
    }
修改为:



/**
     * 图像添加文字
     *
     * @param  string  $text   添加的文字
     * @param  string  $font   字体路径
     * @param  integer $size   字号
     * @param  string  $color  文字颜色
     * @param int      $locate 文字写入位置
     * @param  integer $offset 文字相对当前位置的偏移量
     * @param  integer $angle  文字倾斜角度
     * @param  integer $txt_max_width
     *
     * @return $this
     * @throws ImageException
     */
    public function text($text, $font, $size, $color = '#00000000',
        $locate = self::WATER_SOUTHEAST, $offset = 0, $angle = 0,$txt_max_width = null) {

        if (!is_file($font)) {
            throw new ImageException("不存在的字体文件:{$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 self::WATER_SOUTHEAST:
                $x += $this->info['width'] - $w;
                $y += $this->info['height'] - $h;
                break;
            /* 左下角文字 */
            case self::WATER_SOUTHWEST:
                $y += $this->info['height'] - $h;
                break;
            /* 左上角文字 */
            case self::WATER_NORTHWEST:
                // 起始坐标即为左上角坐标,无需调整
                break;
            /* 右上角文字 */
            case self::WATER_NORTHEAST:
                $x += $this->info['width'] - $w;
                break;
            /* 居中文字 */
            case self::WATER_CENTER:
                $x += ($this->info['width'] - $w) / 2;
                $y += ($this->info['height'] - $h) / 2;
                break;
            /* 下居中文字 */
            case self::WATER_SOUTH:
                $x += ($this->info['width'] - $w) / 2;
                $y += $this->info['height'] - $h;
                break;
            /* 右居中文字 */
            case self::WATER_EAST:
                $x += $this->info['width'] - $w;
                $y += ($this->info['height'] - $h) / 2;
                break;
            /* 上居中文字 */
            case self::WATER_NORTH:
                $x += ($this->info['width'] - $w) / 2;
                break;
            /* 左居中文字 */
            case self::WATER_WEST:
                $y += ($this->info['height'] - $h) / 2;
                break;
            default:
                /* 自定义文字坐标 */
                if (is_array($locate)) {
                    list($posx, $posy) = $locate;
                    $x += $posx;
                    $y += $posy;
                } else {
                    throw new ImageException('不支持的文字位置类型');
                }
        }
        /* 设置偏移量 */
        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)) {
            throw new ImageException('错误的颜色值');
        }
        do {
            if($txt_max_width) {
                //判断是否超出范围
                $str = "";
                for ($i = 0; $i < mb_strlen($text); $i++) {
                    $letter[] = mb_substr($text, $i, 1);
                }

                foreach ($letter as $l) {
                    $teststr = $str . " " . $l;
                    $testbox = imagettfbbox($size, $angle, $font, $teststr);
                    // 判断拼接后的字符串是否超过预设的宽度。超出宽度添加换行
                    if (($testbox[2] > $txt_max_width) && ($str !== "")) {
                        $str .= "\n";
                    }
                    $str .= $l;
                }
                $text = $str;
            }
            /* 写入文字 */
            $col = imagecolorallocatealpha($this->im, $color[0], $color[1], $color[2], $color[3]);
            imagettftext($this->im, $size, $angle, $x + $ox, $y + $oy, $col, $font, $text);
        } while (!empty($this->gif) && $this->gifNext());
        return $this;
    }
增加了一个变量$txt_max_width=null;同时在写入文字上方加入了判断代码:



if($txt_max_width) {
                //判断是否超出范围
                $str = "";
                for ($i = 0; $i < mb_strlen($text); $i++) {
                    $letter[] = mb_substr($text, $i, 1);
                }

                foreach ($letter as $l) {
                    $teststr = $str . " " . $l;
                    $testbox = imagettfbbox($size, $angle, $font, $teststr);
                    // 判断拼接后的字符串是否超过预设的宽度。超出宽度添加换行
                    if (($testbox[2] > $txt_max_width) && ($str !== "")) {
                        $str .= "\n";
                    }
                    $str .= $l;
                }
                $text = $str;
            }
增加的部分代码主要是逐个文字拼接然后判断长度是不是超过了最大的宽度(也就是背景图片的宽度),如果超过就自动加入一个换行符,实现换行,修改完成之后,调用改成:



Image::open(ROOT_PATH . "1.jpg")
            ->text("斯巴奴男装狐狸毛领中长款加厚asdasdsadasdasdasdasdasdasdasdsad白鸭绒","./template/common/fonts/yahei.ttf",20,"#000000",[5,5],0,0,500)
            ->save(ROOT_PATH . "2.jpg",null,100);
        echo "<img src='/2.jpg'>";
然后浏览效果,就变成了如下的情况,实现了自动换行。


TIM截图20181017192604.jpg

原创文章,转载注明出处


我的微信:graent_hu

欢迎扫码加我和微信好友,有什么问题我们可以一起探讨,有什么需要也随时欢迎发消息给我~

转载请注明出处:

本文标题:thinkPHP5图片加文字水印实现换行的方法

本文链接:https://www.wlyc.cn/post-161.html

发表评论

路人甲 表情
看不清楚?点图切换