Underline text using imagettftext

喜夏-厌秋 提交于 2019-12-07 12:44:50

问题


My question is, how do I underline all the text in the image?

Code:

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 ");

RESULT http://i.imgur.com/Jdr7HPy.png

I want all the text to be underlined, I've found some solutions but they're only from left to right, not depending on words.


回答1:


Use the Unicode underline combining character U+0332.

You will need a loop to or clever array merge to modify the text,

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

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

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



回答2:


You can do this by finding out dimensions of the text in pixels using imagettfbbox(), then use it as reference to draw lines beneath the text. I've played around with it and here's my try:

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);
}

Result:

This is a little more flexible that using Unicode chars because you have control over the line height, and position relative to the text above it.



来源:https://stackoverflow.com/questions/14741622/underline-text-using-imagettftext

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!