I'm playing with ImageMagick's "convert" program to add text to an image.
I have something like this (which works): convert "infile.png" -font "font.ttf" -gravity 'south' \ -stroke '#fffc' -strokewidth '3' -pointsize '300' \ -annotate 0 "Test" "outfile.png"
However, the only way I can find to size the text is using the -pointsize option. What I want to do is make the text proportional to the image size, eg have the text work out to 50% of the available width, or similar. I can't find any good way to do this - and nor can I find a suitable query for Google to assist me.
The "convert" program is being called as part of a PHP script so I can be quite flexible in what I do if I need to be (eg if I need to create dummy images to see what sizes they come out as, etc).
Suggestions for other programs I can use instead welcome. I know ImageMagick and I know I can trust it with high quality images if I need to (and will need to here) which is why I stated there.
Mark Rogers wrote:The "convert" program is being called as part of a PHP script so I can be quite flexible in what I do if I need to be (eg if I need to create dummy images to see what sizes they come out as, etc).
Suggestions for other programs I can use instead welcome. I know ImageMagick and I know I can trust it with high quality images if I need to (and will need to here) which is why I stated there.
Why not use PHP's GD libraries? ... following code is *NOT* tested or even run, i just threw it together.
<?php
$im = imagecreatefrompng("infile.png");
$width = imagesx($im); $height = imagesy($im);
// using imagefttext herebecause it uses truetype fonts but look into freetype fonts function // The text to draw $text = 'Testing...'; // Replace path by your own font path $font = 'arial.ttf';
// Add the text imagettftext($im, $width/$somemagicvar, 0, 10, 20, $black, $font, $text); // the $width / $somemagicvar is what is chanign the size to bein proportional... the outputits a size in pts // you can also do using some function or another to work out the width of the textbefore you render ito nto the image.
imagepng($im, "outfile.png"); ?>
Mark Rogers wrote:
I'm playing with ImageMagick's "convert" program to add text to an image.
[...]
However, the only way I can find to size the text is using the -pointsize option. What I want to do is make the text proportional to the image size, eg have the text work out to 50% of the available width, or similar. I can't find any good way to do this [...]
I'd either run identify on the image beforehand, or test PHP's libgd module to see if it was good enough for this.
Hope that helps,
James Taylor wrote:
Why not use PHP's GD libraries? ... following code is *NOT* tested or even run, i just threw it together.
I was under the impression (but admit I haven't tested) that the GD libraries were quicker but lower quality than ImageMagick? I'll do some trials and find out.
I did think about mocking something up with GD and using that to work out the point size, but couldn't see a way to do that either!
MJ Ray wrote:
I'd either run identify on the image beforehand, or test PHP's libgd module to see if it was good enough for this.
I will try GD today and see what the results are like (the results from ImageMagick are pretty amazing, to be honest).
I'm not sure what you mean about using identify though - I can see how I'd use it to work out the size of the image but I can't see how I'd use that information to calculate the pointsize to use with my text?
On Mon, 2009-11-30 at 17:46 +0000, Mark Rogers wrote:
I'm playing with ImageMagick's "convert" program to add text to an image.
I have something like this (which works): convert "infile.png" -font "font.ttf" -gravity 'south' \ -stroke '#fffc' -strokewidth '3' -pointsize '300' \ -annotate 0 "Test" "outfile.png"
However, the only way I can find to size the text is using the -pointsize option. What I want to do is make the text proportional to the image size, eg have the text work out to 50% of the available width, or similar. I can't find any good way to do this - and nor can I find a suitable query for Google to assist me.
If the text is always the same you could experiment manually with one image until you find the proportion you are looking for then divide the image width by the point size you finally settled on to arrive at a pixels/point factor. For each image you do automatically you derive the point size by dividing the width of this particular image by the factor.
If you are using a fixed width font but variable text you could work out the width in pixels for one character at one font size and scale accordingly for the text and width of the images you are working with.
For variable text in a proportional width font you could see if you can get access to the font metric information via one of the libraries that handles true-type fonts, i.e. where you can ask the library "If I draw this text at this point size, how wide will it be?" then by successive approximation refine the point size to get the width you want. I know of FreeType as one such library but there may be others.
HTH, Steve.
Steve Fosdick wrote:
If the text is always the same you could experiment manually with one image until you find the proportion you are looking for then divide the image width by the point size you finally settled on to arrive at a pixels/point factor.
Unfortunately the text will vary.
I thought I could be clever and use the imagettfbbox PHP-GD function to determine the size of the text for any given pointsize, and loop through pointsizes to find a suitable one. And that works incredibly fast, which surprised me. But sadly the result from the GD libraries gives the wrong results when applied to the ImageMagick programs.
Looking again through the ImageMagick docs I've found that various functions do exist for what I want, for example label: and caption: achieve the sizing I need, but I can't see how to actually use them for what I want so I've a dual pronged approach of experimenting wildly and asking on the ImageMagick forums to see which gets me a result first - but at this stage I'm pretty sure ImageMagick will be able to do what I need when I find out how.
I'll post the answer here for anyone who may be interested.
On Tue, 2009-12-01 at 10:56 +0000, Steve Fosdick wrote:
For variable text in a proportional width font you could see if you can get access to the font metric information via one of the libraries that handles true-type fonts, i.e. where you can ask the library "If I draw this text at this point size, how wide will it be?" then by successive approximation refine the point size to get the width you want. I know of FreeType as one such library but there may be others.
Further to this I would try to use the same type library as ImageMagick uses. If you are not able to call the library directly from PHP and need a write a wrapper program I'd put the successive approximation in the program rather than invoke it multiple times.
Regards, Steve.
On 01-Dec-09 09:06:14, Mark Rogers wrote:
MJ Ray wrote:
I'd either run identify on the image beforehand, or test PHP's libgd module to see if it was good enough for this.
I will try GD today and see what the results are like (the results from ImageMagick are pretty amazing, to be honest).
I'm not sure what you mean about using identify though - I can see how I'd use it to work out the size of the image but I can't see how I'd use > that information to calculate the pointsize to use with my text?
-- Mark Rogers // More Solutions Ltd (Peterborough Office) // 0844 251
Your basic problem here is to find the printed length of a given text string, in a given font, at a given point size!
You could incorporate something like the following in a script:
echo "\f[CB]\w'This is my Text'\fP" | troff -Tps
from which the output (to screen, when I entered the above on the command line) is;
x T ps x res 72000 1 1 x init C p1 x font 6 CB f6 s10000 V12000 H72000 md DFd t90000 n12000 0 x trailer V792000 x stop
The key line in there is t90000 which is the evaluation of the width ("\w'...'")of the string "This is my Text" in point-size 10 (the default) using font Courier-Bold ("\f[CB]"). The numerical result "90000" is the length of the text in units of (1 point)/1000, i.e. 1/72000 of an inch, so the physical printed length would be
90000/72000 = 1.25 inches
You could feed that to 'awk' to do the sums (and this time I'll feed in an explicit point-size 15 ("\s[15]...\s0") as well):
echo "\f[CB]\s[15]\w'This is my Text'\s0\fP" | troff -Tps | awk '/^t'/
results in:
t135000
while
echo "\f[CB]\s[15]\w'This is my Text'\s0\fP" | troff -Tps | awk '/^t/{sub(/t/,""); print $0}'
results in
135000
so, finally,
echo "\f[CB]\w'\s[15]This is my Text'\s0\fP" | troff -Tps | awk '/^t/{sub(/t/,""); print $0/72000}'
results in
1.875
which is (15/10)*1.25, the length of "This is my Text" in inches, when printed in Helvetica-Bold in point-size 15. There may be some discrepancy, depending on how spaces are handled in the output.
You can probably exploit the above ideas to get what you want! Hoping this helps, Ted.
-------------------------------------------------------------------- E-Mail: (Ted Harding) Ted.Harding@manchester.ac.uk Fax-to-email: +44 (0)870 094 0861 Date: 01-Dec-09 Time: 12:23:16 ------------------------------ XFMail ------------------------------