Search code examples
phpimage-processinggdimagettftext

Position variable text centered under label using PHP GD


I have successfully outputted text (consisting of 2-3 digit numbers) onto an image using the PHP GD imaging library. Next I would like to position this text and center it under labels included in the image. I have it working now by looking at the image and hardcoding position values, but this is not ideal as the numbers vary and may not be the same length each time the code is run.

Here is a simplified version of what I have so far:

<?php

$font     = 'arial.ttf';
$fontsize = 60;

$value1 = $_GET['r'];
$value2 = $_GET['rm'];
$value3 = $_GET['w'];

$image = imagecreatefrompng('image.png');

$fontcolor = imagecolorallocate($image, 255, 255, 255);

$x1 = 80;
$x2 = 160;
$x3 = 280;
$y = 1050;

imagettftext($image, $fontsize, 0, $x1, $y, $fontcolor, $font, $value1);
imagettftext($image, $fontsize, 0, $x2, $y, $fontcolor, $font, $value2);
imagettftext($image, $fontsize, 0, $x3, $y, $fontcolor, $font, $value3);

header('Content-type: image/png');
imagepng($image);
imagedestroy($image);

?>

I believe that I need to use imagettfbbox, but how do I position the box according to the label in the image?

Is it possible to set a primary position for each label (as they will never move) and center according to that no matter the length of the number? For example, if a 4 digit number was entered it would appear in the same place as a 2 digit number centered under its label.


Solution

  • Box sizing was giving me strange results, so I solved this by creating a function that calculates the number of digits in each number and sends a position variable back.

    function position($value, $pos) {
        $length = strlen((string)$value);
        return $pos - (20 * $length);
    }
    
    $value1 = $_GET['r'];
    $value2 = $_GET['rm'];
    $value3 = $_GET['w'];
    
    $x1 = position($value1, 110);
    $x2 = position($value2, 310);
    $x3 = position($value3, 545);
    $y = 1050;
    
    imagettftext($image, $fontsize, 0, $x1, $y, $fontcolor, $font, $value1);
    imagettftext($image, $fontsize, 0, $x2, $y, $fontcolor, $font, $value2);
    imagettftext($image, $fontsize, 0, $x3, $y, $fontcolor, $font, $value3);