Jump to content

Generate Image with Text on Curved Path


kamdeng

Recommended Posts

Hello, I am a first time poster on these forums.  Hopefully someone can help me and hopefully I can help others in the future.

I am writing a pretty complicated application using PHP & GD to generate images with text.  I need to generate text on a curved path on the fly, something like this:

Curved Up
[img]http://chunkymoon.com/steven/curveup.gif[/img]
&
Curved Down
[img]http://chunkymoon.com/steven/curvedown.gif[/img]

I know that you can create the text at an angle using the function imagettftext, as it is one of the parameters.  If you break a string down to its individual characters then adjust the angle and x and y, I'm sure this is possible.  I just have no clue how to script it.

Any ideas would be much appreciated.  Thanks in advance.
Link to comment
Share on other sites

If you have ImageMagick installed on your server, you could use that. I just had a quick play and came up with this:
[code]<?php
$command = "convert -size 250x80 xc:white -font Verdana -pointsize 18 -annotate +25+65 \"Text on a Curved Path\" -wave -60x500 -crop x110+0+10 test.jpg";
exec($command);
?>[/code]
You'd have to alter some of the commands for different length strings. I'm sure you could do this with GD and write some kinda algorithm to work out the curve, like you said, but that's a bit more invloved. I have some what of an idea how you'd go around this but would require some messing around, I might give it a go when I get home...
Link to comment
Share on other sites

Wow, that's pretty good!  Nice work with ImageMagick.  I've posted on ImageMagick forums before and they said that curved text on a path was not currently possible.  But I guess they were wrong. 

One complaint about this is that it somewhat skews the text towards the sides of the curve as opposed to simply rotating the character it seems to squish it.  I wanted it to look more like my samples images which have the bottom of the character on the path of the curve.  I know, I'm being pretty picky.

And also... like you mentioned I would need to somehow adjust the command based on text length.  Don't know how I would calculate the different parameters.  Because the font, size, and string length are all dynamic and the curved text needs to be generated on the fly.

Thanks for the effort SA.  This is very close!
Link to comment
Share on other sites

Yeah, the ImageMagick method I posted doesn't actually curve the text based on a path, it's more of a cheat/hack of the -wave command more than anything - That's why some of the characters are squashed a bit. If you alter the -wave attributes to something like -60x100 you'll see the actual wave effect which will shape the text into something that looks like a sine wave.

My idea for the GD method was to count the letters in the string and set up some variables to hold string length, height (in px), letter spacing (in px) and incline angle (in degrees) and then do a bit of maths to assign an angle and height value to each character - I guess there would be quite a bit of trial and error involved, especially with me as I'm crap at maths! It might be a bit easier to create  the script that only positions each characters x and y position first, and once that's down, then modify it to add in the change in angle.
Link to comment
Share on other sites

Ok so I've gotten this far.... well actually I found this code somewhere.

[url=http://chunkymoon.com/test.php?text=this%20is%20curved%20text%20]http://chunkymoon.com/test.php?text=this%20is%20curved%20text%20[/url]

[code]<?php

header("Content-type: image/png");
$im = imagecreate(400,200);
$white = imagecolorallocate($im, 255,255,255);
$black = imagecolorallocate($im, 0,0,0);

$cx = 200;
$cy = 100;
$cr = 80;
if (isset($_REQUEST["text"])) {
    $text = $_REQUEST["text"];
} else {
    $text = 'hello there';
}

$length = strlen($text);
$degDelta = 360 / $length;
if ($length > 0) {
    $color = $black;
    for ($x = 0; $x < $length; $x++) {
        // Circular Text
        $AX = $cx - cos(deg2rad($degDelta * $x)) * $cr;
        $AY = $cy - sin(deg2rad($degDelta * $x)) * $cr;

        imagettftext($im, 20, -($degDelta * $x + $degDelta / 2)+90 , $AX, $AY, $color, 'arial.ttf', $text[$x]);

    }
}

imagepng($im);
imagedestroy($im);

?>
[/code]

Almost there... Here is what I need to fix.  I don't want the text to be spread out all the way to make a circle.  So I want each character next to each other on the circular path.  If the string length is long enough so that it goes all the way around the circle that is okay.  But I don't want a 5 letter word spread out all around the circle.  I'm pretty sure this is possible.  I took a stab at it, but completely ruined things.  Anyone good at trigonometry?
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.