Center aligning multiple lines of text with GD and PHP

只谈情不闲聊 提交于 2019-12-05 00:17:12

问题


I'm trying to print multiple lines of text on an image and center align them.

i.e.

    This is
A string of text

Right now, I only have the left position for the whole string. Any shortcuts on getting that to work? I think it might have to be a getttfbox on the whole string, then an explode on the line breaks, then center the new text inside that larger ttfbox. That's a pain in the ass...

EDIT: Came up with a solution:

    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;

In this case, each $string is an array with some information about how and what to print. Hope that helps someone.


回答1:


You can use stil/gd-text class. Disclaimer: I am the author.

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

Demonstration:

demo




回答2:


Here is a function that will use the imagettfbbox you mentioned, I can't help with the automatic wordwrapping, but maybe as you suggested, split the string ahead of time.

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

Edit: Also found this in the PHP documentation comments...

Here's a simple function to wrap text going into an image. It'll wrap onto as many lines as it needs to, but $angle has to be zero. The $width parameter is the width of the image.

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



回答3:


You could use the excellent gd-text library. If you use composer, an example could be this:

<?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:


Get the length of the string (strlen), and an average width of each letter, multiply the strlen result by the average width and then subtract that from your horizontal position.

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

Tell me if it works because I have never tried this



来源:https://stackoverflow.com/questions/9728550/center-aligning-multiple-lines-of-text-with-gd-and-php

标签

工具导航Map