使用 GD 和 PHP 将多行文本居中对齐

Posted

技术标签:

【中文标题】使用 GD 和 PHP 将多行文本居中对齐【英文标题】:Center aligning multiple lines of text with GD and PHP 【发布时间】:2012-03-15 21:35:33 【问题描述】:

我正在尝试在图像上打印多行文本并将它们居中对齐。

    这是一串文本

现在,我只有整个字符串的左侧位置。让它工作的任何捷径?我认为它可能必须是整个字符串上的 getttfbox,然后在换行符上爆炸,然后将新文本居中在那个更大的 ttfbox 内。真是头疼啊……

编辑:想出了一个解决方案:

    foreach ( $strings as $index => $string ) 
        $parts = explode ( "\n", $string['string'] );
        if ( count ( $parts ) > 1 ) 
            $bounds = imagettfbbox ( intval($string['fontsize']), 0, $font, $string['string'] );
            $width = $bounds[2] - $bounds[0];
            $height = $bounds[3] - $bounds[5];
            $line_height = $height / count ( $parts );

            foreach ( $parts as $index => $part ) 
                $bounds = imagettfbbox ( intval($string['fontsize']), 0, $font, $part );
                $new_width = $bounds[2] - $bounds[0];
                $diff = ( $width - $new_width ) / 2;
                $new_left = $string['left'] + $diff;

                $new_string = $string;
                $new_string['left'] = $new_left;
                $new_string['top'] = $string['top'] + ($index * $line_height);
                $new_string['string'] = $part;
                $new_strings[] = $new_string;
            
        
    

    if ( $new_strings )
        $strings = $new_strings;

在这种情况下,每个 $string 都是一个数组,其中包含一些关于如何打印以及打印什么的信息。 希望对某人有所帮助。

【问题讨论】:

请不要将您的答案编辑到您的问题中,而是写一个新答案(并接受它,如果那是对您有用的解决方案)。 【参考方案1】:

您可以使用stil/gd-text 类。免责声明:我是作者。

<?php
use GDText\Box;
use GDText\Color;

$img = imagecreatefromjpeg('image.jpg');

$textbox = new Box($img);
$textbox->setFontSize(12);
$textbox->setFontFace('arial.ttf');
$textbox->setFontColor(new Color(0, 0, 0));
$textbox->setBox(
    50,  // distance from left edge
    50,  // distance from top edge
    200, // textbox width
    100  // textbox height
);

// now we have to align the text horizontally and vertically inside the textbox
$textbox->setTextAlign('center', 'top');
// it accepts multiline text
$textbox->draw("This is\na string of text");

演示:

【讨论】:

我下载了你的代码。它工作得非常好,但可能没有多少人使用它的原因之一是因为它拥有并下载了很多依赖项!你的系统对齐盒子比我平台的客户端和服务器重。如果您可以在没有 /vendor/ 内容的情况下以某种方式使其工作,更像是独立的方法或函数,那么您将拥有很棒的东西。【参考方案2】:

这是一个将使用您提到的 imagettfbbox 的函数,我无法自动换行,但也许按照您的建议,提前拆分字符串。

function imagettftext_cr(&$im, $size, $angle, $x, $y, $color, $fontfile, $text)

  $bbox = imagettfbbox($size, $angle, $fontfile, $text);
  $dx = ($bbox[2]-$bbox[0])/2.0 - ($bbox[2]-$bbox[4])/2.0;
  $dy = ($bbox[3]-$bbox[1])/2.0 + ($bbox[7]-$bbox[1])/2.0;
  $px = $x-$dx;
  $py = $y-$dy;
  return imagettftext($im, $size, $angle, $px, $py, $color, $fontfile, $text);

编辑:在 PHP 文档 cmets 中也找到了这个...

这是一个将文本换行到图像中的简单函数。它会包裹 尽可能多的行,但 $angle 必须为零。这 $width 参数是图片的宽度。

function wrap($fontSize, $angle, $fontFace, $string, $width)

  $ret = "";
  $arr = explode(' ', $string);
  foreach ( $arr as $word )
  
    $teststring = $ret.' '.$word;
    $testbox = imagettfbbox($fontSize, $angle, $fontFace, $teststring);
    if ( $testbox[2] > $width )
      $ret.=($ret==""?"":"\n").$word;
     else 
      $ret.=($ret==""?"":' ').$word;
    
  
  return $ret;

【讨论】:

问题是,它不是在图像本身上居中对齐,而是相对于其他文本行居中对齐。即图像可以是 500px 宽,文本的左侧可以是 100px,文本宽度可以是 150px 并且有 2 行,并且文本应该居中对齐。 那么我猜你需要逐行 imagettftext_cr() 正如你已经提到的。 php.net/manual/en/function.imagettftext.php在2008年3月14日03:36搜索“sk89q”的帖子 是的,这还不是我所需要的。很酷,我会写函数,我只是希望有人有捷径 是的,我不知道有一个 PHP 函数可以在没有迭代的情况下立即执行此操作。【参考方案3】:

您可以使用出色的 gd-text 库。 如果你使用作曲家,一个例子可能是这样的:

<?php
require __DIR__.'/../vendor/autoload.php';

use GDText\Box;

$im = imagecreatetruecolor(500, 500);
$backgroundColor = imagecolorallocate($im, 0, 18, 64);
imagefill($im, 0, 0, $backgroundColor);

$box = new Box($im);
$box->setFontFace(__DIR__.'/Pacifico.ttf'); // http://www.dafont.com/pacifico.font
$box->setFontSize(80);
$box->setFontColor([255, 255, 255]);
$box->setTextShadow([0, 0, 0, 50], 0, -2);
$box->setLeading(0.7);
$box->setBox(20, 20, 460, 460);
$box->setTextAlign('center', 'center');
$box->draw("Pacifico");

header("Content-type: image/png");
imagepng($im);

【讨论】:

【参考方案4】:
This is my code which works:

function textWithImage($text)  
                $imagePath="/images/fb-share-bg.jpg";
                $im = imagecreatefromjpeg($imagePath);
                $txtColor = imageColorAllocate($im, 255, 255, 255);  
                $font="/fonts/OpenSans-Bold.ttf";
                $description=$text;
                $in =  wordwrap($description,50,"|",true);
                $st = explode("|",$in);
                //$inStrArr=str_split($description,60);
                $inStrArr=$st;
                $addOnYVal=0;
                foreach($inStrArr as $key=>$value)
                    if($key!=0)
                        $addOnYVal+=40;
                    
                    list($x, $y) = pc_ImageTTFCenter($im, $value, $font, 20,$addOnYVal);
                    ImageTTFText($im,20,0, $x, $y, $txtColor, $font, $value);
                

               $newImagename="/uploads/".$img;
               imagejpeg($im, $newImagename,100);

 // Enf of textWithImage function



function pc_ImageTTFCenter($image, $text, $font, $size, $addOnYVal) 
    // find the size of the image
    $xi = ImageSX($image);
    $yi = ImageSY($image);

    // find the size of the text
    $box = ImageTTFBBox($size, $angle, $font, $text);

    $xr = abs(max($box[2], $box[4]));
    $yr = abs(max($box[5], $box[7]));

    // compute centering
    $x = intval(($xi - $xr) / 2);
    $y = intval(($yi + $yr) / 2) +  + $addOnYVal;;

    return array($x, $y);


// Calling function
$text = "This is to center alignn the text on image";

textWithImage($text);

//  Output: Image will be saved in the upload folder

【讨论】:

【参考方案5】:

获取字符串的长度 (strlen) 和每个字母的平均宽度,将 strlen 结果乘以平均宽度,然后从水平位置中减去。

$text="center this";
$h=50;
$h=(strlen($text)*15)-$h;

告诉我它是否有效,因为我从未尝试过这个

【讨论】:

这对我正在尝试做的事情并没有真正的意义。不过还是谢谢。

以上是关于使用 GD 和 PHP 将多行文本居中对齐的主要内容,如果未能解决你的问题,请参考以下文章

如何将导航栏大标题转换为多行,居中对齐

如何将图像垂直对齐到某些文本第一行的中心?

在 PHP 中从文本创建图像 - 如何制作多行?

如何将文本左对齐。在反应工具提示中?

如何将多行文本字段(动态、文本居中)垂直居中到另一个 MovieClip?

使用 PIL 居中/中间对齐文本?