使用imagettftext下划线文本

3

我的问题是如何在图像中下划线所有文本?

代码:

function createImage($text)
{
    $text .= "\n";
    $text = wordwrap($text, 40, "\n");
    $newlines = substr_count($text, "\n");
    if($newlines == 0)
    {
        $height = 30;
    }
    else
    {
        $height = 30*$newlines-$newlines*7;
    }
    putenv('GDFONTPATH=' . realpath('.'));
    header('Content-Type: image/png');

    $im = imagecreatetruecolor(315, $height);
    $white = imagecolorallocate($im, 255, 255, 255);
    $grey = imagecolorallocate($im, 128, 128, 128);
    $black = imagecolorallocate($im, 0, 0, 0);
    $purple = imagecolorallocate($im, 97, 26, 139);
    imagefilledrectangle($im, 0, 0, 399, $height, $white);
    $font = 'arialbd.ttf';

    imagettftext($im, 11, 0, 10, 20, $purple, $font, $text);
    imagepng($im);
    imagedestroy($im);
}

createImage("Stackoverflow Stackoverflow Stackoverflow Stackoverflow Stackoverflow Stackoverflow Stackoverflow Stackoverflow Stackoverflow Stackoverflow Stackoverflow Stackoverflow ");

结果 http://i.imgur.com/Jdr7HPy.png

我希望所有文本都能被下划线,我找到一些解决方案,但它们只是从左到右,并不依赖于单词。

2个回答

4

使用Unicode下划线组合字符U+0332。

你需要循环或巧妙地合并数组来修改文本。

$e = explode(' ', $text);

for($i=0;$i<count($e);$i++) {
  $e[$i] = implode('&#x0332;', str_split($e[$i]));
}

$text = implode(' ', $e);

createImage("Stackoverflow"); 输出 S#x0332;t#0332;... 通过您的循环,感谢您的快速回复。 - William N
& #x0332; 这里缺少了 & 符号 :) - William N
啊,好的!我更新了我的答案。 - shapeshifter

2

您可以通过使用imagettfbbox()获取文本的像素尺寸,然后将其用作绘制文本下方线条的参考。我已经尝试过了,以下是我的方法:

function createImage($text){

  putenv('GDFONTPATH=' . realpath('.'));

  $text = wordwrap($text, 40, "\n");  
  $padding = 10;                         // padding around text
  $uOffs = 2;                            // distance between the line and the text above it
  $uHeight = 1;                          // height of the under-line
  $lines = explode("\n", $text);         // split text in lines
  $lineLengths = array();                // will store length of each line
  $textSize = 11;
  $font = 'arialbd.ttf';

  // bounding box of all text
  $textBoundingBox = array_map('abs', imagettfbbox($textSize, 0, $font, $text));

  list($blx, $bly, $brx, $bry, $trx, $try, $tlx, $tly) = $textBoundingBox;

  // calculate image dimensions based on the bounding box data
  $x = max($brx, $trx) + ($padding * 4);
  $y = max($blx, $bly) + ($padding * 4);

  $img = imagecreatetruecolor($x, $y);

  // determine length of each line of text
  foreach($lines as $i => $line){
    $box = imagettfbbox($textSize, 0, $font, $line);
    $lineLengths[$i] = max($box[2], $box[4]);
  }

  $white = imagecolorallocate($img, 255, 255, 255);
  $grey = imagecolorallocate($img, 128, 128, 128);
  $black = imagecolorallocate($img, 0, 0, 0);
  $purple = imagecolorallocate($img, 97, 26, 139);
  imagefilledrectangle($img, 0, 0, $x - 1, $y - 1, $white);  

  imagettftext($img, $textSize, 0, $padding + min($tlx, $blx), $padding + min($tly, $bly), $purple, $font, $text);

  // starting Y position of the under-line
  $uY = $padding +  min($tly, $bly);

  // underline text...
  foreach($lineLengths as $length){
    imagefilledrectangle($img, $padding + min($tlx, $blx), $uY + $uOffs, $padding + $length, $uY + $uOffs + $uHeight, $purple);
    $uY += 19;
  }  

  header('Content-Type: image/png');
  imagepng($img);
  imagedestroy($img);
}

结果:

在这里输入图片描述

这种方法比使用Unicode字符更加灵活,因为您可以控制行高以及与上面文本的相对位置。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接