franz_ludilabel Posted January 14, 2016 Share Posted January 14, 2016 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 Quote Link to comment Share on other sites More sharing options...
Muddy_Funster Posted January 14, 2016 Share Posted January 14, 2016 Too much like math's for me, but I'm sure the man himself will be able to help you out fairly soon. Quote Link to comment Share on other sites More sharing options...
Barand Posted January 14, 2016 Share Posted January 14, 2016 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; } } ?> 1 Quote Link to comment Share on other sites More sharing options...
franz_ludilabel Posted January 15, 2016 Author Share Posted January 15, 2016 Thank you Barand, With your explanations, I was able to get what I want in a matter of seconds. Your code is still useful nowadays and works pretty well Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.