PHPFixing
  • Privacy Policy
  • TOS
  • Ask Question
  • Contact Us
  • Home
  • PHP
  • Programming
  • SQL Injection
  • Web3.0

Tuesday, October 11, 2022

[FIXED] How to resize gd image to fit with text written in it?

 October 11, 2022     gd, php     No comments   

Issue

I want to resize a GD image so that its contents fit inside the image.

Is this distinctly possible?


Solution

The biggest problem is to recover the size of the text. Imagettftext as well as imagettfbox returns an array of points that describe the position of the text in your image, but not the area that allow you to logically fit an image to it.

Here is what I mean :

function demo($text, $size, $angle, $font)
{
    $gdh = imagecreatetruecolor(300, 300);
    $white = imagecolorallocate($gdh, 255, 255, 255);
    imagefill($gdh, 0, 0, $white);

    $black = imagecolorallocate($gdh, 0, 0, 0);
    $rect = imagettftext($gdh, $size, $angle, 50, 250, $black, $font, $text);

    // Display a rectangle using the teturn of imagettftext
    $red = imagecolorallocate($gdh, 255, 0, 0);
    imageline($gdh, $rect[0], $rect[1], $rect[2], $rect[3], $red);
    imageline($gdh, $rect[0], $rect[1], $rect[6], $rect[7], $red);
    imageline($gdh, $rect[2], $rect[3], $rect[4], $rect[5], $red);
    imageline($gdh, $rect[4], $rect[5], $rect[6], $rect[7], $red);

    // Calculate and display the real area we need to fit our image
    $blue = imagecolorallocate($gdh, 0, 0, 255);
    $minX = min(array ($rect[0], $rect[2], $rect[4], $rect[6]));
    $maxX = max(array ($rect[0], $rect[2], $rect[4], $rect[6]));
    $minY = min(array ($rect[1], $rect[3], $rect[5], $rect[7]));
    $maxY = max(array ($rect[1], $rect[3], $rect[5], $rect[7]));
    imageline($gdh, $minX, $minY, $minX, $maxY, $blue);
    imageline($gdh, $maxX, $minY, $maxX, $maxY, $blue);
    imageline($gdh, $minX, $minY, $maxX, $minY, $blue);
    imageline($gdh, $minX, $maxY, $maxX, $maxY, $blue);

    header("Content-type: image/png");
    imagepng($gdh);
    die();
} 

If we call :

demo("Cheers!", 48, 45, "font.ttf");

We'll get this image :

enter image description here

You can see in red the area given by imagettfbox, and in blue the calculated area that will allow us to define a new image size, fitted to the text.

Here is a solution to fit text to an image (replace font.ttf by your own font of course).

function fitImageToText($gdh, $text, $size, $angle, $font)
{
    // Recover the box size where we will be able to put our text
    // Took from the doc http://www.php.net/manual/en/function.imagettfbbox.php#105593
    putenv('GDFONTPATH=' . realpath('.'));
    $rect = imagettfbbox($size, $angle, $font, $text);
    $minX = min(array ($rect[0], $rect[2], $rect[4], $rect[6]));
    $maxX = max(array ($rect[0], $rect[2], $rect[4], $rect[6]));
    $minY = min(array ($rect[1], $rect[3], $rect[5], $rect[7]));
    $maxY = max(array ($rect[1], $rect[3], $rect[5], $rect[7]));
    $targetWidth = $maxX - $minX;
    $targetHeight = $maxY - $minY;
    $srcWidth = imagesx($gdh);
    $srcHeight = imagesy($gdh);

    // Creating target image
    $targetGdh = imagecreatetruecolor($targetWidth, $targetHeight);
    imagealphablending($targetGdh, false);
    imagesavealpha($targetGdh, true);
    imagecopyresampled($targetGdh, $gdh, 0, 0, 0, 0, $targetWidth, $targetHeight, $srcWidth, $srcHeight);

    // Writting text inside the new image
    $red = imagecolorallocate($targetGdh, 255, 0, 0);
    imagettftext($targetGdh, $size, $angle, abs($minX), abs($minY), $red, $font, $text);

    return $targetGdh;
}

To call it :

$gdh = imagecreatefrompng("cheers.png");
$newGdh = fitImageToText($gdh, "Cheers!", 48, 45, "font.ttf");
imagedestroy($gdh);

// Outputs the image
header("Content-type: image/png");
imagepng($newGdh);
imagedestroy($newGdh);
die();

Original picture :

enter image description here

Resulting picture :

enter image description here

Note : aspect ratio of your source image will be fit to the text size without any logic. If you want to preserve aspect ratio of your image, you can use something like this :

function fitImageToText($gdh, $text, $size, $angle, $font)
{
    // Recover the box size where we will be able to put our text
    // Took from the doc http://www.php.net/manual/en/function.imagettfbbox.php#105593
    putenv('GDFONTPATH=' . realpath('.'));
    $rect = imagettfbbox($size, $angle, $font, $text);
    $minX = min(array ($rect[0], $rect[2], $rect[4], $rect[6]));
    $maxX = max(array ($rect[0], $rect[2], $rect[4], $rect[6]));
    $minY = min(array ($rect[1], $rect[3], $rect[5], $rect[7]));
    $maxY = max(array ($rect[1], $rect[3], $rect[5], $rect[7]));
    $targetWidth = $maxX - $minX;
    $targetHeight = $maxY - $minY;
    $srcWidth = imagesx($gdh);
    $srcHeight = imagesy($gdh);

    // Recovering new source image size respecting its aspect ratio
    $srcRatio = $srcWidth / $srcHeight;
    $targetRatio = $targetWidth / $targetHeight;
    if ($srcWidth <= $targetWidth && $srcHeight <= $targetHeight)
    {
        $imgTargetWidth = $srcWidth;
        $imgTargetHeight = $srcHeight;
    }
    else if ($targetRatio > $srcRatio)
    {
        $imgTargetWidth = (int) ($targetHeight * $srcRatio);
        $imgTargetHeight = $targetHeight;
    }
    else
    {
        $imgTargetWidth = $targetWidth;
        $imgTargetHeight = (int) ($targetHeight / $srcRatio);
    }

    // Creating target image
    $targetGdh = imagecreatetruecolor($targetWidth, $targetHeight);
    imagealphablending($targetGdh, false);
    imagesavealpha($targetGdh, true);
    imagecopyresampled($targetGdh, $gdh, 0, 0, 0, 0, $imgTargetWidth, $imgTargetHeight, $srcWidth, $srcHeight);

    // Writting text inside the new image
    $red = imagecolorallocate($targetGdh, 255, 0, 0);
    imagettftext($targetGdh, $size, $angle, abs($minX), abs($minY), $red, $font, $text);

    return $targetGdh;
}

This will result in :

enter image description here



Answered By - Alain Tiemblo
Answer Checked By - Marie Seifert (PHPFixing Admin)
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg
Newer Post Older Post Home

0 Comments:

Post a Comment

Note: Only a member of this blog may post a comment.

Total Pageviews

Featured Post

Why Learn PHP Programming

Why Learn PHP Programming A widely-used open source scripting language PHP is one of the most popular programming languages in the world. It...

Subscribe To

Posts
Atom
Posts
Comments
Atom
Comments

Copyright © PHPFixing