将 PHP 生成的图片动态文本居中对齐

20

我希望将生成在图片上的文本居中对齐。目前,我不确定是否可以实现对齐。以下是代码。

$im = @imagecreatefromjpeg('poloroid.jpg');

// Create some colors
$white = imagecolorallocate($im, 255, 255, 255);
$grey = imagecolorallocate($im, 128, 128, 128);
$black = imagecolorallocate($im, 0, 0, 0);
//imagefilledrectangle($im, 0, 0, 399, 29, $white);

// The text to draw
//$text = 'John...';
$fbid = $_POST["id"]; 
$text = $_POST["want"];
$fb_email =$_POST["email"];
$fb_name=$_POST["name"];

$uploads_dir = 'uploaded_files/';
// Replace path by your own font path
$font = 'verdana.ttf';

//image file name
//$name ="$fbid.png";
$name = $uploads_dir.$fbid.".png"; //this saves the image inside uploaded_files folder

// Add some shadow to the text
imagettftext($im, 20, 0,  25, 126, $grey, $font, $text);

// Add the text
imagettftext($im, 20, 0, 25, 125, $black, $font, $text);

// Using imagepng() results in clearer text compared with imagejpeg()
//imagepng($im);
imagepng($im,$name,9);
imagedestroy($im);

谢谢大家的帮助。

4个回答

41
$im = @imagecreatefromjpeg('poloroid.jpg');

// Create some colors
$white = imagecolorallocate($im, 255, 255, 255);
$grey = imagecolorallocate($im, 128, 128, 128);
$black = imagecolorallocate($im, 0, 0, 0);
//imagefilledrectangle($im, 0, 0, 399, 29, $white);

// The text to draw
//$text = 'John...';
$fbid = $_POST["id"]; 
$text = $_POST["want"];
$fb_email =$_POST["email"];
$fb_name=$_POST["name"];

$uploads_dir = 'uploaded_files/';
// Replace path by your own font path
$font = 'verdana.ttf';
$font_size = 20;
$angle = 45;

//image file name
//$name ="$fbid.png";
$name = $uploads_dir.$fbid.".png"; //this saves the image inside uploaded_files folder

// Get image Width and Height
$image_width = imagesx($im);  
$image_height = imagesy($im);

// Get Bounding Box Size
$text_box = imagettfbbox($font_size,$angle,$font,$text);

// Get your Text Width and Height
$text_width = $text_box[2]-$text_box[0];
$text_height = $text_box[7]-$text_box[1];

// Calculate coordinates of the text
$x = ($image_width/2) - ($text_width/2);
$y = ($image_height/2) - ($text_height/2);

// Add some shadow to the text
imagettftext($im, $font_size, 0, $x, $y+1, $grey, $font, $text);

// Add the text
imagettftext($im, $font_size, 0, $x, $y, $black, $font, $text);

// Using imagepng() results in clearer text compared with imagejpeg()
//imagepng($im);
imagepng($im,$name,9);
imagedestroy($im);

我使用了这段代码。但是由于宽度的差异,图像位置不同了。对吗? - Shazery Nasir
我不明白,请说得更具体一些。 - Fr0z3n
5
计算文本边界框高度的代码应该是:$text_height = $text_box[7]-$text_box[1]; - 上面的代码错误地将其计算为0。遗憾的是,我不能编辑单个字符... - John
根据@John的评论进行了编辑。还添加了对imagettfbbox()文档的引用,以证明此更改的合理性。 - Guillaume Boudreau
以上代码在居中方面对我来说不太准确。我将$text_width更改为:$text_width = abs($text_box[4] - $text_box[0]) + 10; 和 $text_height = $text_box[7]-$text_box[1]; 并设置$angle = 0; 然后一切都居中正确了。希望能帮到其他人! - Kupe
1
根据文档xy坐标表示基线起点的坐标,因此这不会使其居中。 - Victor

28
你可以使用 stil/gd-text 类。免责声明:我是作者。
<?php
use GDText\Box;
use GDText\Color;

$im = @imagecreatefromjpeg('poloroid.jpg');

$textbox = new Box($im);
$textbox->setFontSize(20);
$textbox->setFontFace('verdana.ttf');
$textbox->setFontColor(new Color(0, 0, 0)); // black
$textbox->setTextShadow(
    new Color(0, 0, 0, 80), // black color, but 60% transparent
    0,
    -1 // shadow shifted 1px to top
);
$textbox->setBox(
    0,  // distance from left edge
    0,  // distance from top edge
    imagesx($im), // textbox width, equal to image width
    imagesy($im)  // textbox height, equal to image height
);

// now we have to align the text horizontally and vertically inside the textbox
// the texbox covers whole image, so text will be centered relatively to it
$textbox->setTextAlign('center', 'center');
// it accepts multiline text
$textbox->draw($text);

$uploads_dir = 'uploaded_files/';
//image file name
//$name ="$fbid.png";
$name = $uploads_dir.$fbid.".png"; //this saves the image inside uploaded_files folder
imagepng($im, $name, 9);
imagedestroy($im);

演示:

demo


非常棒,使用它。 - ropic
太棒了。它非常易用。文档写得很好。 - smartrahat
嘿,这个很好用。有没有办法自动增加字体大小,直到字体填满整个宽度?例如,如果我正在制作一个标志生成器,希望单词“example”填满整个宽度 - 指定填充? - Brian Klug
@smartrahat 我该如何设置多个段落?比如我怎么知道第一个段落在哪个坐标结束,然后相应地为第二个段落及其后面的段落设置框大小?我尝试了标记作者,但不知何故它没有链接。 - Kunal

1
我稍微更新了你的代码:

function ImageTTFCenter($image, $text, $font, $size, $angle = 45) 
{
    $xi = imagesx($image);
    $yi = imagesy($image);

    $box = imagettfbbox($size, $angle, $font, $text);

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

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

    return array($x, $y);
}

$im = @imagecreatefromjpeg('poloroid.jpg');

// Create some colors
$white = imagecolorallocate($im, 255, 255, 255);
$grey = imagecolorallocate($im, 128, 128, 128);
$black = imagecolorallocate($im, 0, 0, 0);
//imagefilledrectangle($im, 0, 0, 399, 29, $white);

// The text to draw
//$text = 'John...';
$fbid = $_POST["id"]; 
$text = $_POST["want"];
$fb_email =$_POST["email"];
$fb_name=$_POST["name"];

$uploads_dir = 'uploaded_files/';
// Replace path by your own font path
$font = 'verdana.ttf';

//image file name
//$name ="$fbid.png";
$name = $uploads_dir.$fbid.".png"; //this saves the image inside uploaded_files folder

list($x, $y) = ImageTTFCenter($im, $text, $font, 20)
// Add some shadow to the4 text
imagettftext($im, 20, 0, $x, $y+1, $grey, $font, $text);

// Add the text
imagettftext($im, 20, 0, $x, $y, $black, $font, $text);

// Using imagepng() results in clearer text compared with imagejpeg()
//imagepng($im);
imagepng($im,$name,9);
imagedestroy($im);

“ImageTTFCenter” 函数将查找您要向其提供 “imagettftext” 的图片的中心坐标。”

3
我明白您的意思,这句话的意思是将文本的起始位置对齐到中间,但并不把文本居中对齐。 - Shazery Nasir

-2
foreach ($user as $key=>$value){    
    $bb = imagettfbbox($value['font-size'],0,$fontname,$value['name']);    
    $WW = abs($bb[2]-$bb[0]);    
    $XX = ($value['XPos']+$WW);    
    $HH = abs($bb[5]-$bb[3]);    
    $HH +=1;
    $HHH += $HH;
    imagettftext($im, $value['font-size'], 0, $value['XPos'],   $value['YPos'], $color[$value['color']], $fontname, $value['name']);  
    $HHH += 1;
    $WIDE = abs($bb[2]-$bb[0]);  
    $endpoint=$value['XPos']+$WIDE;  
    $bb2 = imagettfbbox($value['font-size'],0,$fontname,$value['name']);  
    $WW2 = abs($bb2[2]-$bb2[0]);     
    $x2pos= $endpoint-$WW2;    
    imagettftext($im, $value['font-size'], 0, $x2pos, $value['YPos'], $color[$value['color']], $fontname, $value['name']);
}

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