如何使用GD库包装写在图像上的文本 [英] How to wrap text written on an image with the GD library

查看:78
本文介绍了如何使用GD库包装写在图像上的文本的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何使用PHP图像生成功能将长文本放置在图像上,选择区域,水平对齐方式,垂直对齐方式,并使长文本单词正确包裹在所选区域中?

How can I use the PHP image generation functions to place long text over an image, choosing an area, a horizontal alignment, a vertical alignment, and letting long text word wrap correctly in the chosen area?

这可以复制并在其他语言中变得有用吗?

Can this be replicated and become useful in other languages?

推荐答案

PHP函数imagettftext(...)可以编写文本,但不支持长文本换行,因此必须将文本分成单词,并且每个单词都必须分开调用imagettfbbox(...)计算单词边界并测试单词是否应该换行.

PHP function imagettftext(...) can write text but does not support wrapping of long text, so you must divide the text in words, and for each word call imagettfbbox(...) to calculate the word boundary and test if the word should go on a new line.

要使文本垂直对齐,必须在知道文本的总高度时将渲染推迟到最后.

To be able to vertical align the text you must defer rendering till the end, when you know the total height of the text.

这是代码.

演示用途

<?php


// Image params

    $imgWidth = 240;
    $imgHeight = 900;


// Text params

    $text='Tanto va la gatta al lardo che ci lascia lo zampino!';
    $drawFrame=array(10,340,$imgWidth-10,$imgHeight-140);
    $fontType = 'ArialBlack.ttf';
    $fontSize = 30;
    $lineHeight=32;
    $wordSpacing=' ';
    $hAlign=0; // -1:left  0:center 1:right
    $vAlign=0; // -1:top  0:middle 1:bottom


// allocate

    $img = imagecreatetruecolor($imgWidth,$imgHeight);
    $background = imagecolorallocate($img, 78,129,154);
    $textColor = imagecolorallocate($img, 255,255,255);

// debug show text area

    $area_color = imagecolorallocate($img, 255,0,0);
    imagerectangle ($img, $drawFrame[0], $drawFrame[1], $drawFrame[2], $drawFrame[3], $area_color);

// write text

    wrapimagettftext($img, $fontSize, $drawFrame, $textColor,$fontType, $text, '100%',' ',$hAlign,$vAlign);

// output image

    header("Content-type: image/png");
    imagepng($img);
    imagecolordeallocate($img, $textColor );
    imagecolordeallocate($img, $background );

?>

主要功能

<?php


function wrapimagettftext($img, $fontSize, $drawFrame, $textColor,$fontType, $text, $lineHeight='',$wordSpacing='',$hAlign=0,$vAlign=0) {

    if($wordSpacing===' ' || $wordSpacing==='') {
        $size = imagettfbbox($fontSize, 0, $fontType, ' ');
        $wordSpacing=abs($size[4]-$size[0]);
    }
    $size = imagettfbbox($fontSize, 0, $fontType, 'Zltfgyjp');
    $baseHeight=abs($size[5]-$size[1]);
    $size = imagettfbbox($fontSize, 0, $fontType, 'Zltf');
    $topHeight=abs($size[5]-$size[1]);

    if($lineHeight==='' || $lineHeight==='') {
        $lineHeight=$baseHeight*110/100;
    } else if(is_string($lineHeight) && $lineHeight{strlen($lineHeight)-1}==='%') {
        $lineHeight=floatVal(substr($lineHeight,0,-1));
        $lineHeight=$baseHeight*$lineHeight/100;
    } else {

    }

    $usableWidth=$drawFrame[2]-$drawFrame[0];
    $usableHeight=$drawFrame[3]-$drawFrame[1];

    $leftX=$drawFrame[0];
    $centerX=$drawFrame[0]+$usableWidth/2;
    $rightX=$drawFrame[0]+$usableWidth;

    $topY=$drawFrame[1];
    $centerY=$drawFrame[1]+$usableHeight/2;
    $bottomY=$drawFrame[1]+$usableHeight;

    $text = explode(" ", $text);

    $line_w=-$wordSpacing;
    $line_h=0;
    $total_w=0;
    $total_h=0;
    $total_lines=0;

    $toWrite=array();
    $pendingLastLine=array();

    for($i=0;$i<count($text);$i++) {
        $size = imagettfbbox($fontSize, 0, $fontType, $text[$i]);

        $width = abs($size[4] - $size[0]);
        $height = abs($size[5] - $size[1]);

        $x = -$size[0]-$width/2;
        $y = $size[1]+$height/2;

        if($line_w+$wordSpacing+$width>$usableWidth) {
            $lastLineW=$line_w;
            $lastLineH=$line_h;

            if($total_w<$lastLineW) $total_w=$lastLineW;
            $total_h+=$lineHeight;

            foreach($pendingLastLine as $aPendingWord) {

                if($hAlign<0) $tx=$leftX+$aPendingWord['tx'];
                else if($hAlign>0) $tx=$rightX-$lastLineW+$aPendingWord['tx'];
                else if($hAlign==0) $tx=$centerX-$lastLineW/2+$aPendingWord['tx'];

                $toWrite[]=array('line'=>$total_lines,'x'=>$tx,'y'=>$total_h,'txt'=>$aPendingWord['txt']);
            }
            $pendingLastLine=array();

            $total_lines++;
            $line_w=$width;
            $line_h=$height;

            $pendingLastLine[]=array('tx'=>0,'w'=>$width,'h'=>$height,'x'=>$x,'y'=>$y,'txt'=>$text[$i]);
        } else {

            $line_w+=$wordSpacing;
            $pendingLastLine[]=array('tx'=>$line_w,'h'=>$width,'w'=>$height,'x'=>$x,'y'=>$y,'txt'=>$text[$i]);
            $line_w+=$width;
            if($line_h<$height) $line_h=$height;
        }
    }

    $lastLineW=$line_w;
    $lastLineH=$line_h;

    if($total_w<$lastLineW) $total_w=$lastLineW;
    $total_h+=$lineHeight;

    foreach($pendingLastLine as $aPendingWord) {

        if($hAlign<0) $tx=$leftX+$aPendingWord['tx'];
        else if($hAlign>0) $tx=$rightX-$lastLineW+$aPendingWord['tx'];
        else if($hAlign==0) $tx=$centerX-$lastLineW/2+$aPendingWord['tx'];

        $toWrite[]=array('line'=>$total_lines,'x'=>$tx,'y'=>$total_h,'txt'=>$aPendingWord['txt']);
    }
    $pendingLastLine=array();
    $total_lines++;

    $total_h+=$lineHeight-$topHeight;

    foreach($toWrite as $aWord) {

        $posx = $aWord['x'];

        if($vAlign<0) $posy=$topY+$aWord['y'];
        else if($vAlign>0) $posy=$bottomY-$total_h+$aWord['y'];
        else if($vAlign==0) $posy=$centerY-$total_h/2+$aWord['y'];

        imagettftext($img, $fontSize, 0, $posx, $posy , $textColor, $fontType, $aWord['txt']);

    }
}
?>

这篇关于如何使用GD库包装写在图像上的文本的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆