N
N
NibiruanChild2015-02-12 14:55:44
PHP
NibiruanChild, 2015-02-12 14:55:44

How to make a picture from text inscribed in a rectangle in PHP?

The essence of the task: to create an image of a certain width from the text. It’s easy to write on an image or create an empty canvas on imagick and write over it, but there are 2 difficulties, more precisely subtasks:
1. there is text of arbitrary length, there is a rectangle whose width and height are set and fixed, you need to dynamically calculate the size, taking into account the font features ( not all fonts are monospaced, they come with long tails and different widths for each letter)
2. there is text of arbitrary length, now the font size is fixed, the image width is fixed, dynamic height
3. in both tasks it is also desirable to stretch the text in width, except for the last line
I really don’t want to manually parse the fonts, are there any ready-made functions, api, or at least for working with fonts that allow you to quickly get information.

Answer the question

In order to leave comments, you need to log in

3 answer(s)
L
Leonid Sysoletin, 2015-02-12
@sysoletin

RTFM Imagick::queryFontMetrics

N
NibiruanChild, 2015-02-12
@NibiruanChild

The coder from me is still the same, but it seems that task 2 has been completed. Suddenly someone needs:

function wordWrapAnnotation($image, $draw, $text, $maxWidth)
{
    $words = preg_split('%\s%', $text, -1, PREG_SPLIT_NO_EMPTY);
    $lines = array();
    $i = 0;
    $lineHeight = 0;
    while (count($words) > 0)
    {
        $metrics = $image->queryFontMetrics($draw, implode(' ', array_slice($words, 0, ++$i)));
        $lineHeight = max($metrics['textHeight'], $lineHeight);

        if ($metrics['textWidth'] > $maxWidth or count($words) < $i)
        {
            $lines[] = implode(' ', array_slice($words, 0, --$i));
            $words = array_slice($words, $i);
            $i = 0;
        }
    }

    return array($lines, $lineHeight);
}

function createImageFromText($text){

    $maxWidth = 900;
    $font = 'BookmanOld.ttf';
    $fontSize = 34;
    $filename = 'res.png';
    $padding = 10;

    /* Create a new Imagick object */
    $image = new Imagick();
    $image->newImage(1, 1, 'white'); // none = transparent
    $image->setImageFormat("png");

    /* Create an ImagickDraw object */
    $draw = new ImagickDraw();

    /* Set the font */
    $draw->setFont($font);
    $draw->setFontSize($fontSize);

    list($lines, $lineHeight) = wordWrapAnnotation($image, $draw, $text, $maxWidth);
    $image->newImage($maxWidth+$padding, $padding+ count($lines)*$lineHeight, 'none'); // none = transparent    

    for($i = 0; $i < count($lines); $i++)
        $image->annotateImage($draw, $padding, + ($i+1)*$lineHeight, 0, $lines[$i]);

    //$image->writeImage($filename);
    return $image;
    
}

createImageFromText('бла бла бла текст абракадабрматьеезаногу')->writeImage('res.png');

I
index0h, 2015-02-12
@index0h

1. You generate a picture with text and a transparent background (you get its dimensions)
2. You superimpose [1] on a rectangle. With resizing and positioning if necessary

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question