Центрировать текст на изображении с помощью PHP GD

Итак, я создаю генератор баннеров.

Я буду добавлять текст посередине, но хотел бы, чтобы он был точно по центру. Я знаю, что imagettftext можно использовать для записи на баннере, но это не будет центрировать его.

Вероятное решение могло бы состоять в том, чтобы найти ширину текста, а затем использовать половину его, отняв от половины ширины баннера, но я понятия не имею, как это сделать.

Я использую PHP-GD и не хочу использовать что-либо еще, что мне придется устанавливать.

imagettftext($img, 14, 0, (468 - ((strlen($_GET['description']) * imagefontwidth(imageloadfont('minecraft.ttf'))) / 1)), 85, imagecolorallocate($img, 0, 0, 0), 'minecraft.ttf', $_GET['description']);

Код выше делает результат выше. С маленькими строками все в порядке, но должно быть что-то не так, поскольку, как только они становятся длинными, происходит сбой.


person ThePixelPony    schedule 07.04.2014    source источник


Ответы (4)


Проверьте imagettfbbox: http://www.php.net/manual/en/function.imagettfbbox.php. Это даст вам экстенты текста, который вы хотите отобразить. Тогда это простая арифметика, чтобы центрировать это на вашем изображении.

person Kryten    schedule 07.04.2014
comment
Ага, понятно. Итак, делает ли PHP GD все загружаемые шрифты фиксированной ширины? - person ThePixelPony; 07.04.2014
comment
Я бы так не думал. Я ничего не знаю о внутренней работе GD, но я думаю, что он вычисляет ширину и высоту каждого символа, учитывая любые отступы, поля или что-то еще, а затем дает вам итоги. - person Kryten; 07.04.2014

Вы можете центрировать текст, получив ширину от внешних границ из imageftbbox, а затем разделив ее на два, чтобы получить смещение, которое будет центрировать текст на изображении.

// Get image dimensions
  $width = imagesx($image);
  $height = imagesy($image);
// Get center coordinates of image
  $centerX = $width / 2;
  $centerY = $height / 2;
// Get size of text
  list($left, $bottom, $right, , , $top) = imageftbbox($font_size, $angle, $font, $text);
// Determine offset of text
  $left_offset = ($right - $left) / 2;
  $top_offset = ($bottom - $top) / 2;
// Generate coordinates
  $x = $centerX - $left_offset;
  $y = $centerY + $top_offset;
// Add text to image
  imagettftext($image, $font_size, $angle, $x, $y, $color, $font, $text);

документация по imageftbbox

person Tyler    schedule 21.01.2016
comment
$y = $centerY - top_offset; должно быть $y = $centerY + $top_offset; - person Antony D'Andrea; 27.01.2017
comment
Нет, $top_offset нужно вычесть из координаты $centerY, чтобы учесть высоту текста. Если вы вместо этого добавите $top_offset, текст будет отображаться ниже центра. - person Tyler; 11.09.2017
comment
С уважением, получил результат, который я намеревался добавить по какой-то причине. - person Antony D'Andrea; 12.09.2017
comment
Ваше $top_offset положительное или отрицательное? - person Tyler; 09.10.2017

У меня ушло много времени, но я понял, как точно центрировать текст на изображении.

list($left,, $right) = imageftbbox(18, 0, 'minecraft.ttf', $_GET['description']);
$dwidth = $right - $left;
$pos = (HALF_OF_IMAGE_WIDTH - $nwidth / 2);
person ThePixelPony    schedule 08.04.2014

Вы можете центрировать текст на изображении, получив половину высоты и ширины изображения, а также половину высоты и ширины текста

Вы можете получить ширину и высоту изображения, используя imagesx и imagesy соответственно.
Вы можете получить ширину и высоту текста, используя imagettfbbox в PHP GD.

После того, как вы получите привязку, вы можете получить ширину и высоту текста
ширина текста = правая граница по x - левая граница по оси x
высота текста = нижняя граница по оси y - верхняя граница по оси y

Затем используйте ширину и высоту изображения, чтобы получить начальное смещение, которое позволит центрировать изображение.
start_x_offset = (imagewidth - textwidth) / 2;
start_y_offset = (imageheight - textheight) / 2;

// Get image dimensions
$image_width = imagesx($image);
$image_height = imagesy($image);

$text_bound = imageftbbox($font_size, $angle, $font, $text);

//Get the text upper, lower, left and right corner bounds
$lower_left_x =  $text_bound[0]; 
$lower_left_y =  $text_bound[1];
$lower_right_x = $text_bound[2];
$lower_right_y = $text_bound[3];
$upper_right_x = $text_bound[4];
$upper_right_y = $text_bound[5];
$upper_left_x =  $text_bound[6];
$upper_left_y =  $text_bound[7];


//Get Text Width and text height
$text_width =  $lower_right_x - $lower_left_x; //or  $upper_right_x - $upper_left_x
$text_height = $lower_right_y - $upper_right_y; //or  $lower_left_y - $upper_left_y

//Get the starting position for centering
$start_x_offset = ($image_width - $text_width) / 2;
$start_y_offset = ($image_height - $text_height) / 2;

// Add text to image
imagettftext($image, $font_size, $angle, $start_x_offset, $start_y_offset, $color, $font, $text);
person Tosin Amuda    schedule 14.12.2017