Skip to content
MagickCmd › ImageMagick add text to image

ImageMagick add text to image

Burn text into an image with ImageMagick. Positioning with -gravity and -annotate, readable drop shadows, choosing fonts, and fixing CJK text that renders as empty boxes.

Two operators draw text: -annotate and -draw. Use -annotate — it respects -gravity, which means you can position text relative to an edge without knowing the image dimensions.

A basic caption

magick input.jpg -gravity south -pointsize 48 -fill white \
  -annotate +0+28 'Your caption here' output.jpg

With -gravity south, the offset +0+28 means 28 pixels inward from the bottom edge, horizontally centred. Change the gravity and the same offset is measured from a different edge.

Text that stays readable on any photo

White text disappears over a bright sky; black text disappears in shadow. Draw it twice — dark offset by a pixel, then the real colour on top:

magick input.jpg -gravity southeast -pointsize 42 \
  -fill black -annotate +26+22 '© 2026 Your Name' \
  -fill white -annotate +24+24 '© 2026 Your Name' output.jpg

Cheap, and far more robust than guessing a colour. The alternative is a translucent box behind the text:

magick input.jpg -gravity south -pointsize 36 \
  -undercolor '#00000080' -fill white -annotate +0+24 'Caption' output.jpg

-undercolor takes 8-digit hex, so the last two characters are the alpha.

Choosing a font

magick -list font

That prints every font ImageMagick knows about. Pass one by family name, or give a full path to a font file:

magick input.jpg -font DejaVu-Sans-Bold -pointsize 48 \
  -fill white -gravity center -annotate 0 'Hello' output.jpg

If the list is empty

You are missing the fontconfig delegate, or the machine has no fonts at all. This is extremely common in slim Docker images. Install some:

apt install fonts-dejavu-core

If text renders as empty boxes

The font has no glyphs for those characters. The default fonts cover Latin only, so Chinese, Japanese, Korean, Arabic and emoji all come out as boxes. Pass a font that covers them, by full path:

magick input.jpg \
  -font /usr/share/fonts/truetype/noto/NotoSansCJK-Regular.ttc \
  -pointsize 48 -fill white -gravity south -annotate +0+30 '你好世界' output.jpg

Sizing text relative to the image

A fixed -pointsize looks tiny on a 4000px photo and enormous on a thumbnail. Either compute it in your script, or let ImageMagick fit the text to a box:

magick input.jpg -gravity south -size 1000x120 \
  -background none -fill white label:'Fitted caption' \
  -composite output.jpg

label: chooses the largest point size that fits the given -size.

Create a text-only image

magick -background none -fill '#0d9488' -pointsize 96 \
  label:'MagickCmd' output.png

Related

Copied