Controlling the size of overlayed text

Questions and postings pertaining to the usage of ImageMagick regardless of the interface. This includes the command-line utilities, as well as the C and C++ APIs. Usage questions are like "How do I use ImageMagick to create drop shadows?".
Post Reply
hollymcr
Posts: 9
Joined: 2009-12-01T03:56:35-07:00
Authentication code: 8675309

Controlling the size of overlayed text

Post by hollymcr »

I need to overlay some text over an image, and currently have this working:

Code: Select all

convert infile.png -font font.ttf -gravity south \
    -stroke "#000C" -strokewidth 3 -pointsize 400 \
    -annotate 0 "Welcome to my world" \
    -resize 1024x768 outfile.png
The original image is quite large (3400x1020) and using pointsize 400 means my text covers 100% of the width. The final -resize will vary depending on usage (the final result will not resize at all, but intermediate results are resized for quick proofing of results).

What I want to do is have pointsize calculated automatically so that I can specify the text size as a percentage of the total image size (or I'm happy stating it in pixels relative to the original image). In other words, what I'd like to do is something like this:

Code: Select all

#This doesn't work!
convert infile.png -font font.ttf -gravity south \
    -stroke "#000C" -strokewidth 3 -size 3400x1020 \
    -annotate 0 "Welcome to my world" \
    -resize 1024x768 outfile.png
or

Code: Select all

#This doesn't work either!
convert infile.png -font font.ttf -gravity south \
    -stroke "#000C" -strokewidth 3 -size 100% \
    -annotate 0 "Welcome to my world" \
    -resize 1024x768 outfile.png
but -size doesn't work that way. What is the correct way to do this?

What if I wanted to do 80% instead of 100%?

If I want instead to start by defining a bounding box for the text over the image, then let the text be scaled to fit within that box (with gravity applied as necessary), what is the best way then?
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: Controlling the size of overlayed text

Post by fmw42 »

-annotate uses whatever pointsize you specify and places it according to -gravity and the -annotate coordinate arguments. It knows nothing about the image size. Thus if you have too large a pointsize, it will overflow the image.

The only way I know to do what you want is to specify the width (in pixels) you want and use label: (or caption:) to create your text on a transparent background. It will find the closest pointsize that will fit that width. Then composite that over your background image where ever you want it placed using -gravity and/or -geometry. See http://www.imagemagick.org/Usage/text/#label

You will have to precompute the width you want from the image width and the percent you want.

newwidth=`convert yourimage -format "%[fx:80*w/100]" info:`

will give you 80% width of the image. Then use -size ${newwidth}x with your label:
hollymcr
Posts: 9
Joined: 2009-12-01T03:56:35-07:00
Authentication code: 8675309

Re: Controlling the size of overlayed text

Post by hollymcr »

Label (and caption) look ideal, but I can't see how to composite the image and text (and possibly multiple text items) in a single step. Are there any examples of this? (I have looked through the examples and it is fantastic how many there are, but I couldn't see one that helped me get where I wanted). Should I be starting with convert or composite?

If I want to move to doing this from a PHP script using the PHP Imagick libraries, will that make my life easier or harder?
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: Controlling the size of overlayed text

Post by fmw42 »

hollymcr wrote:Label (and caption) look ideal, but I can't see how to composite the image and text (and possibly multiple text items) in a single step. Are there any examples of this? (I have looked through the examples and it is fantastic how many there are, but I couldn't see one that helped me get where I wanted). Should I be starting with convert or composite?

If I want to move to doing this from a PHP script using the PHP Imagick libraries, will that make my life easier or harder?

You need to use two lines. The first to get the desired width and the second the do the text creation with label and then composite over your background image. Something like

newwidth=`convert yourimage -format "%[fx:80*w/100]" info:`
convert yourimage \( -size ${newwidth}x -background none -font ... -fill ... -stroke ... -strokewidth ... label:"some text" \) \
-gravity ... -composite outimage

see parenthesis processing at http://www.imagemagick.org/Usage/basics/#parenthesis

If you are going to use PHP, I would suggest using the exec command rather than Imagick as I have found some differences in results in what little I have used with either. But you can try Imagick and see what you find. Calculating the newwidth can be done in PHP without needing IM.
Post Reply