50行带码搞定PHP GD库绘制文本段落

支持自动换行、像素定位、限宽、任意对齐方式、RGB和哈希颜色值,返回实际起点坐标和宽高

/*绝大部分情况下九种对齐方式就足够用了,本方法是以传入的$x、$y值为参照点,根据$pos值进行相对偏移,从左向右、从上往下分9个点*/
public static function writeOnImg(\GdImage &$img,string $str,int $maxWidth,int $fontSize,int $x,int $y,int|string $color,int $pos=0,int $lineHeight=0,string $font='path/to/fontFile.ttf') : array
{
    if($str=='') return [$x,$y,0,0];
    if($lineHeight<1) $lineHeight=intval($fontSize*1.6); //默认行高是字符尺寸的1.6倍
    $arr=preg_split('/(?<!^)(?!$)/u',$str);
    $i=0;
    $lines=[''];
    $width=0;
    foreach($arr AS $w){
        if($w!==PHP_EOL){
            $box=imagettfbbox($fontSize,0,$font,$lines[$i].$w);
            $lineWidth=$box[2]-$box[0];
            if($lineWidth<=$maxWidth){ //如果未超宽就拼接到本行
                if($lineWidth>$width) $width=$lineWidth; //实际宽度取最大值
                $lines[$i].=$w;
            }else $lines[++$i]=$w; //如果超宽了就重启一行
        }else $lines[++$i]='';  //遇到换行符就重启一行
    }
    //计算实际高度,此时$box刚好在最后一行,当然前提是最后一个字符不能是换行符!
    $height=(count($lines)-1)*$lineHeight+$box[7]-$box[1];
    if($pos>0){
        $x=(int)round($x-$pos%3/2*$width); //横向偏移
        $y=(int)round($y-intval($pos/3)/2*$height); //竖向偏移
    }
    if(is_string($color)) $color=self::setImgColor($img,$color);
    foreach($lines AS $line => $text){
        if($text!=='') imagettftext($img,$fontSize,0,$x,$lineHeight*$line+$y,$color,$font,$text);
    }
    return [$x,$y,$width,$height];
}
/*设定颜色*/
public static function setImgColor(\GdImage $img,string $color) : int
{
    preg_match("/^rgb\(([0-9]{0,3})\,\s*([0-9]{0,3})\,\s*([0-9]{0,3})\)/",$color,$match);
    if(!isset($match[3])||!is_numeric($match[1])||!is_numeric($match[2])||!is_numeric($match[3])){
        $color=str_replace('#','',$color);
        switch(strlen($color)){
            case 3:
                $r=substr($color,0,1);
                $g=substr($color,1,1);
                $b=substr($color,2,1);
                $arr=[hexdec($r.$r),hexdec($g.$g),hexdec($b.$b)];
                break;
            case 6:
                $arr=[hexdec(substr($color,0,2)),hexdec(substr($color,2,2)),hexdec(substr($color,4,2))];
                break;
            default: throw new \MyException('未知的哈希颜色值!');
        }
    }else $arr=array_slice($match,1,3);
    return imagecolorallocate($img,...$arr);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值