1

I'm using PHP imageftbbox to create some dates that are calculated and rendered as an image.

They currently render to an image block so my font size is largely irrelevant apart from for creating higher resolution results. The problem I have is that if I have for instance the result provide two different dates (say February and March) then the font sizes appear differently in my resulting page as obviously it's expanding the March date to fill the box.

How can I make the sizing apply to what the font size actually spits out - so I can for instance have the same size font output no matter what the length of the content created?

    <?php
include 'deliverytimes.php';

$date = new DateTime();
$now = date("Y-m-d H:i:s");
$h = date("H:i:s"); 

$days = explode(",", $businessDaysToAdd);
if (count($days) > 1) {
      
    $two_weekdays_later_1 = strtotime(date("Y-m-d H:i:s", strtotime($now)) . " +" . $days[0] . " weekdays $h");
    $date_1 = new DateTime("@$two_weekdays_later_1"); 
    $formattedDeliveryDate_1 =  $date_1->format('jS M');
    $formattedDeliveryDate_3 =  $date_1->format('jS \o\f F');
    
    $two_weekdays_later_2 = strtotime(date("Y-m-d H:i:s", strtotime($now)) . " +" . $days[1] . " weekdays $h");
    $date_2 = new DateTime("@$two_weekdays_later_2"); 
    $formattedDeliveryDate_2 =  $date_2->format('jS M.');
    $formattedDeliveryDate_4 =  $date_2->format('jS \o\f F');   

    $formattedDeliveryDate1 = $formattedDeliveryDate_3;
    $formattedDeliveryDate2 = $formattedDeliveryDate_4;

    $formattedDeliveryDate = "If ordered today we estimate delivery to be approximately between " . $formattedDeliveryDate_1 . " and " . $formattedDeliveryDate_2;
} else {
    $h = date("H:i:s");   
    $two_weekdays_later = strtotime(date("Y-m-d H:i:s", strtotime($now)) . " +" . $businessDaysToAdd . " weekdays $h");
    $date = new DateTime("@$two_weekdays_later"); 
    $formattedDeliveryDate = "If ordered today we estimate delivery approximately by " . $date->format('l, jS M.');
}

$defaultOutput = 'main';
$textMobile = isset($_REQUEST['mobile']) ? $_REQUEST['mobile'] : $defaultOutput;

switch($textMobile) {
    case "main":
        $textToUse = $formattedDeliveryDate;
        break;
    case "p1":
        $textToUse = $formattedDeliveryDate1;        
        break;
    case "p2":
        $textToUse = $formattedDeliveryDate2;        
        break;
}

// Path to our font file
$font = './Inter-SemiBold.ttf';
$fontBold = './Inter-Bold.ttf';
$size = 24;
$size2 = 82;
$spacing = 0;
$bbox   = imageftbbox($size2, 0, $fontBold, $textToUse);
$width  = $bbox[2] - $bbox[6];
$height = $bbox[3] - $bbox[7];
$im    = imagecreatetruecolor($width, $height);
$xcoord = ($width - $bbox[4]) / 2;
imagealphablending($im, false);
imagesavealpha($im, true);
$white = imagecolorallocate($im, 255, 255, 255);
$black = imagecolorallocate($im, 0, 0, 0);
$grey = imagecolorallocate($im, 161, 161, 168);
$trans = imagecolorallocatealpha($im, 255, 255, 255, 127);
imagefilledrectangle($im, 0, 0, $width, $height, $trans);
//$red = imagecolorallocate($im, 239, 73, 52);

$defaultTextColour = 'white';
$textColour = isset($_REQUEST['colour']) ? $_REQUEST['colour'] : $defaultTextColour;

switch($textColour) {
    case "white":
        $textColourUse = $white;
        break;
    case "black":
        $textColourUse = $black;        
        break;
    case "grey":
        $textColourUse = $grey;        
        break;
}

// Write it
imagettftext($im, $size2, 0, -$bbox[6], -$bbox[7], $textColourUse, $fontBold, $textToUse);

// Output to browser
header('Content-Type: image/png');
header("Cache-Control: no-store, no-cache, must-revalidate, max-age=0");
header("Cache-Control: post-check=0, pre-check=0", false);
header("Pragma: no-cache");
imagepng($im);
imagedestroy($i'm);

My CSS is just

.phpimage2 {max-width:90%; display: block; margin:10px auto 5px auto}
Danny Shepherd
  • 363
  • 1
  • 3
  • 17

1 Answers1

0

From what I can see, given your code, is that you generate an image of which the width depends on the $textToUse variable. I tried your code, and this is what I get (half the original size):

enter image description here

My best guess is that you use these image in another page, where you have fixed the width at which these image are displayed. Since the March image is less wide than the February image, it will get stretched to the same width as the February image. The result you see on your page is probably something like this:

enter image description here

However, this is only a guess, because the code in your question doesn't allow us to actually reproduce your problem. See also: How to create a Minimal, Reproducible Example.

What would a solution be? You could use CSS to scale the image: transform: scale(0.5);, this would allow you to reduce it to a fixed font size. This might not work on a responsive page, where the bounding box can vary a lot in size. It all depends on how the image is embedded in the page, and you haven't told us.

KIKO Software
  • 15,283
  • 3
  • 18
  • 33
  • Thanks Kiko - I thought I had missed something obvious there but I've only got the following CSS code used - `.phpimage2 {max-width:90%; display: block; margin:10px auto 5px auto}` For some reason the image always comes out as 468px x 55px – Danny Shepherd Dec 08 '20 at 11:34
  • i've added some extra code to my listing - the start of the php which generates dates but might affect size that I haven't noticed. – Danny Shepherd Dec 08 '20 at 11:37
  • KIKO, you're absolutely right. Max-width alone was causing it, I need to use zoom to get it to be right. Though i'm not sure every browser supports that still. – Danny Shepherd Dec 08 '20 at 12:10
  • @DannyShepherd I'm glad you managed to solve your problem. – KIKO Software Dec 08 '20 at 12:20
  • the only problem i've got now is zoom:50% works perfectly, transform scale makes them both the same width again and zoom doesn't work in Firefox, so i'm not sure how to do it. – Danny Shepherd Dec 08 '20 at 12:59
  • I still don't know what your HTML/CSS page looks like, but I'll give it a try. – KIKO Software Dec 08 '20 at 13:12
  • A simple transform seems to do the job. Not sure what your problem is now. See: [Using transform](https://jsfiddle.net/KIKO_Software/exba7y10/3/) This does work in Firefox. I would not use zoom, see: [CanIUse](https://caniuse.com/css-zoom) – KIKO Software Dec 08 '20 at 13:18
  • I've posted some info about that here - https://stackoverflow.com/questions/65200260/text-images-adapt-with-css-transform-responsive-design-within-grid-remove-zoom Unfortunately I cannot use anything but CSS to achieve it due to where the content is going, so hopefully there is a pure CSS option that scales with responsive design and flex grids too. – Danny Shepherd Dec 08 '20 at 13:53
  • back to this one. I need to create a box in php that has a fixed width or its impossible to have the font sizes scale at the same rate. I've done that but now that i've created a fixed width `$width = 1010;` in the code the text is no longer centered - any ideas how I can center the text in the image again? – Danny Shepherd Dec 08 '20 at 23:07
  • @DannyShepherd You subtract the width of the text from the width of the image (1010 pixels), and move the text to the right by half of the result. – KIKO Software Dec 08 '20 at 23:59
  • Kiko you might have an answer/edit of my code for this related issue. If I can sort this i've finally got everything working the way I want - https://stackoverflow.com/questions/65239769/php-imageftbbox-imagettftext-simple-letter-spacing-kerning – Danny Shepherd Dec 11 '20 at 12:28