Jump to content

Text on curve


franz_ludilabel

Recommended Posts

Hi,

 

I am on a project where I need to create some curved text inside an image. To generate a preview of a web-to-print tool...

 

I first started by looking for an SVG solution. I installed last versions of the imagemagick + librsvg2 (even had to compile because some people said that it supports good svg conversion only in last versions) to convert svg file into png file, but didnt work. While normal text are correctly rendered, The <textPath> xml node of svg is ignored by the convert tool of librsvg2.

 

Then I tried GD and the imagettftext() function, mainly because Im using PHP on the server side.

 

If you dont know, the trick is to draw every letter one by one and put a different angle on each of them.

The result was not perfect because as each letter was separated by the same distance, there were some holes because of less width letters.

 

Then I found out the Barand code, who is an active user on this forum that helps with that : 

 

Here you can find his code : 

http://forums.phpfreaks.com/topic/57542-image-manipulation-skewing-text-text-on-a-curve/

 

But I dont understand the $s and $e parameters.

The last feature that I need is to vertically center the text, but cant find how because I dont understand the role of $s and $e variables.

 

Can someone read his code and enlighten me ?

 

Dont hesitate to ask questions if necessary :) Thanks for your help

Link to comment
Share on other sites

Don't resurrect old posts.

 

$s and $e are the start and end angles of the arc, as imagearc() in the manual would tell you. The text is centred on the midpoint of the arc. (NOTE: the angles for the text are in a clockwise direction, whereas for imagearc they are anticlockwise)

 

Some of the lines were out of order in that old post, so I have changed the top few lines

<?php
/*********************************************
* Fitting text to arc
*
* TextOnArc
* Author   :  Barand August2007
**********************************************/
$im = imagecreate(400,400);

$white = imagecolorallocate($im, 0xFF, 0xFF, 0xFF);
$grey  = imagecolorallocate($im, 0xCC, 0xCC, 0xCC);
$txtcol = imagecolorallocate($im, 0xFF, 0x00, 0x00);

$r = 150;
$cx = 200;
$cy = 200;
$txt1 = 'Text on an Arc';
$txt2 = 'by Barand';
$font = 'c:/windows/fonts/arial.ttf';
$size = 48;

$pad = 2;                      // extra char spacing for text
$s = 180;
$e = 360;
imagearc($im,$cx,$cy,$r*2,$r*2,$s,$e,$grey);
textOnArc($im,$cx,$cy,$r,$s,$e,$txtcol,$txt1,$font,$size,$pad);

$s = 90;
$e = 90;
$pad = 3;                      // extra char spacing for text
$size = 24;

textInsideArc($im,$cx,$cy,$r,$s,$e,$txtcol,$txt2,$font,$size,$pad);

header("content-type: image/png");
imagepng($im);
imagedestroy($im);

function textWidth($txt, $font, $size)
{
    $bbox = imagettfbbox($size,0,$font,$txt);
    $w = abs($bbox[4]-$bbox[0]);
    return $w;
}

function textOnArc($im,$cx,$cy,$r,$s,$e,$txtcol,$txt,$font,$size, $pad=0)
{
    $tlen = strlen($txt);
    $arccentre = ($e + $s)/2;
    $total_width = textWidth($txt, $font, $size) - ($tlen-1)*$pad;
    $textangle = rad2deg($total_width / $r);
    $s = $arccentre - $textangle/2;
    $e = $arccentre + $textangle/2;
    for ($i=0, $theta = deg2rad($s); $i < $tlen; $i++)
    {
        $ch = $txt{$i};
        $tx = $cx + $r*cos($theta);
        $ty = $cy + $r*sin($theta);
        $dtheta = (textWidth($ch,$font,$size))/$r;
        $angle = rad2deg(M_PI*3/2 - ($dtheta/2 + $theta) );
        imagettftext($im, $size, $angle, $tx, $ty, $txtcol, $font, $ch);
        $theta += $dtheta;
    }
}

function textInsideArc($im,$cx,$cy,$r,$s,$e,$txtcol,$txt,$font,$size, $pad=0)
{
    $tlen = strlen($txt);
    $arccentre = ($e + $s)/2;
    $total_width = textWidth($txt, $font, $size) + ($tlen-1)*$pad;
    $textangle = rad2deg($total_width / $r);
    $s = $arccentre - $textangle/2;
    $e = $arccentre + $textangle/2;
    for ($i=0, $theta = deg2rad($e); $i < $tlen; $i++)
    {
        $ch = $txt{$i};
        $tx = $cx + $r*cos($theta);
        $ty = $cy + $r*sin($theta);
        $dtheta = (textWidth($ch,$font,$size)+$pad)/$r;
        $angle = rad2deg(M_PI/2 - ($theta - $dtheta/2));
        imagettftext($im, $size, $angle, $tx, $ty, $txtcol, $font, $ch);
        $theta -= $dtheta;
    }
}


?>

post-3105-0-23590500-1452775066_thumb.png

  • Like 1
Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.