I have a bunch of jpeg images. Say 001abcd.jpg, 002abcd.jpg, and so on.

I want to capture the filename and add it as a text in the image itself in one corner. So the result would be, for example, the file 003abcd.jpg will have "003abcd" imprinted in one corner of that image. (The extension need not be there.)

I want a terminal command that can batch process hundreds of images and add its own filenames in its respective images.

I am using Linux Mint 17.

Something tells me that imagemagick can be useful, but I don't know scripting.

It is easy to put a single common text in all images. but I don't know how to put unique filenames as the text in the respective images in one go.


mogrify does batch processing so you could use something like this (change the font, size, color, position etc as per your taste):

mogrify -font Liberation-Sans -fill white -undercolor '#00000080' \
-pointsize 26 -gravity NorthEast -annotate +10+10 %t *.jpg

to add the file name without extension (%t) to all jpgs in the current dir, e.g. orca-lm-1.jpg:

enter image description here

This will overwrite your files so make sure you have backup copies.
If you use a different format (e.g. png) for the output files then the original files will remain unchanged:

mogrify -format 'png' -font Liberation-Sans -fill white -undercolor \
'#00000080' -pointsize 26 -gravity NorthEast -annotate +10+10 %t *.jpg

Indeed you can use ImageMagick to write text into an image. Use the convert utility to transform an image to a new file (or mogrify to transform a file in place, but I don't recommend it, because if you make a mistake, you lose the original). You specify the text with the -annotate option, which can contain escape sequences such as %t for the file name without directory or extension. There are many more options that let you control the position, size, font, color, etc.

Suppose your files are in a subdirectory called original of the current directory. Create a directory labeled:

mkdir labeled

To convert the images, call convert like this:

convert original/001abcd.jpg -fill green -pointsize 20 -annotate +0+0 %t -gravity north-east labeled/001abcd.jpg

The first parameter after -annotate is the geometry, which indicates the location of the text. +0+0 is the corner; the -gravity north-east says that this is the top right corner. The second parameter is the text, which here is just the escape sequence that says “use the file name”.

To convert all the .jpg files in the directory, write a loop. The wildcard pattern *.jpg represents the list of .jpg files, to this loop acts on all the .jpg files in the original directory. In the loop body, "$x" refers to the file name with the directory part; "${x##*/}" refers to the file name without the directory part.

for x in original/*.jpg; do
  convert "$x" original/001abcd.jpg -fill green -pointsize 20 -annotate +0+0 %t -gravity north-east "labeled/${x##*/}"
  • Thank you. It works well. Instead of '-annotate +0+0' I would recommend using '-annotate +2+22' to make text visible and with 2 pixels margin. Oct 11 '21 at 15:16

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.