Overlaying an image's filename using ImageMagick (or similar) - image-processing

I know ImageMagick's annotate command can superimpose some text over an image, but can it use the image's filename as this text? I would've assumed so, but can't seem to find direct documentation that confirms this.
No doubt some combination of parameters can manage this, or is there a better way of doing this in a script?

Eric L.'s answer is correct -- +1 from me for it! -- but -annotate doesn't give you much control over the appearance of the text.
If you look for prettyness, then rather go for something that uses -composite. You can use an IM command to construct an overlay image first (which uses a semi-transparent background) and then overlay it over the original image.
Here is an example how to do it with -composite instead of -annotate, using a scripted approach that processes every PNG file in the current directory. This one even automatically adapts the font size and fits it into the available "width * 90%" -- it is a Bash script (see comments for Win equivalent):
for img in *.png; do
width=$(identify -format %W ${img})
width=$(( ${width} * 9 / 10 ))
convert \
-background '#0008' \
-gravity center \
-fill white \
-size ${width}x100 \
caption:"${img}" \
"${img}" \
+swap \
-gravity south \
-composite \
"with-caption-${img}"
done
An example illustration for one original and the respective output are below:
!
Here is a command that uses -annotate, trying to set a few things beyond the default parameters:
for img in so#12231624-right.png; do
convert \
"${img}" \
-fill red \
-undercolor '#0008' \
-pointsize 24 \
-gravity south \
-annotate +0+5 "${img}" \
"with-annotate-${img}"
done

It's a very old entry but I find it each time I search for this topic, and it doesn't work (for me at least). Here something that works for me:
convert input.jpg -gravity South -annotate 0 '%f' output.jpg
Hope this helps someone...

You can also use mogrify to add text to bunch of images at once.
mogrify -gravity South -annotate 0 '%f' -pointsize 24 -fill white *.png
This will overwrite existing images, so make sure you have a backup before you execute this.

Building on Steve Czetty's solution, it looks like you can set the text size and color of the annotation, using -pointsize and -fill, respectively.
Here's an example:
convert input.jpg -gravity south -pointsize 24 -fill yellow -annotate 0 '%f' output.jpg
Obviously, you can change the text size from 24 points to something else, as well the color, from 'yellow' to some other color, as per your preference.

Related

Perspective + montage with overlap of multiple images at the command-line

I have a collection (of variable size) of rectangular images (frames extracted from a source video file with ffmpeg), and am trying to find a way to automatically generate a "filmstrip" at the command line, ideally one in which each image is rotated to give it a perspective, and then partly overlayed with the previous one.
The output would be something like this (with transparent background)
(Note: Numbers in the corner would be a plus...)
I imagine ImageMagick has the tools for this, but so far I've not found any obvious way of achieving this...
Any pointer?
Here's something that worked quite nicely for me:
-virtual-pixel transparent +distort Perspective '0,0 0,0 0,110 0,110 200,0 100,20 200,110 100,80' \
-gravity South -background transparent -splice 0x15 \
-font Arial -pointsize 12 -gravity southwest -annotate +2+0 "%[p]" \
miff:- | \
montage -geometry 100x\>-20+2 -tile x1 -background none - montage_test.png```
![montage](https://i.stack.imgur.com/ezplh.png)

Is there anyway to batch create 30+ logos but change text on each one?

I need to create 30+ logos in a similar style to this:
http://www.manchestertaxicomparison.co.uk/wp-content/themes/ilfordtaxis/images/logo.png
Only thing that changes will be the top text, i.e Manchester -> Newcastle
I have to do this many time and as such would love to know if there is anyway to automate it.
Kind regards,
Jack
Personally, I would do it with ImageMagick at the command line like this:
convert -pointsize 72 -background none -fill "rgb(254,203,54)" \
label:"LEEDS" -resize 170x30! base.png +swap \
-geometry +40+0 -composite result.png
And then do all 30 of them in a simple loop:
#!/bin/bash
for city in LEEDS LIVERPOOL EDINBURGH CARDIFF; do
convert -pointsize 72 -background none -fill "rgb(254,203,54)" label:"$city" -resize 170x30! base.png +swap -geometry +40+0 -composite "$city.png"
done
Note that there are other words not necessarily visible on StackOveflow's white background.
ImageMagick is installed on most Linux distros and is available for macOS and Windows.

Start path relative to corner of image

I have written the following script which uses the ImageMagick* convert utility to append axis labels to an existing image.
LEFT_="l -30,0 +2,+2 -6,-2 +6,-2 -2,+2 z"
RIGHT_="l 30,0 -2,+2 +6,-2 -6,-2 +2,+2 z"
convert -size 240x160 pattern:SMALLFISHSCALES \
-pointsize 16 -fill black -background white \
-gravity SouthEast -splice 0x20 \
-draw "translate 40,0 text 0,0 'Time' stroke red path 'm 5,2 $RIGHT_'" \
-gravity NorthWest -splice 20x0 \
-draw "rotate +90 translate 40,-10 text 0,0 'Value' path 'm -5,2 $LEFT_'" \
example.png
Which produces the following image:
This is almost exactly what I am after, except that the red arrow is out of place. I expected the red arrow to appear next to the Time label, since its start point is specified as a relative position in the same draw command. Unfortunately, it looks like the -gravity option is affecting the text primitive, but not the path primitive.
Is there a way to reference the SouthEast corner, or the Time text label when specifying the start position of the red arrow? I can't use absolute coordinates, because the size of the image varies.
*ImageMagick 6.7.8-9 on CentOS 7
Updated Answer
Maybe you can make Unicode text arrows like this then they will be affected by gravity...
perl -e 'binmode(STDOUT,":utf8"); print "Time ... \x{2192}\x{2191}";'|
convert -font TimesNewRoman -pointsize 36 label:#- arrows.png
Depending on your OS, the following may do as a replacement for the Perl above...
printf "%b" "\u2192" | convert ...
Original Answer
I am not at all familiar with paths, but I can suggest a way to achieve what you want that doesn't use gravity at all, and maybe that will help.
Rather than use -splice, you can clone your original image and crop it to the size you planned to splice on, and then -append the strips that label the axes. It is easier to show you the command than explain it!
convert -size 240x160 pattern:SMALLFISHSCALES \
\( +clone -crop x20+0+0 -fill blue -colorize 100% \) \
-append \
\( +clone -crop 20x+0+0 -fill red -colorize 100% \) \
+swap +append result.png
I have filled the x-axis blue, but remove that and add whatever labelling and arrows you need, and I filled the y-axis red, but likewise remove that and add labelling and arrows - rotating as necessary.
Two tricky things to note...
-append will append the second image below the first
+append will append the second image to the right of the first, so I +swap beforehand to put it on the left side.

ImageMagick: redraw a text without "-draw" for only outward stroke

I try to create a text image with ImageMagick, where is the stroke expands only outward. I found a solution, where I should use the "-draw" command, but with it I would need the size of my image, but I don't know it in advance.
The command below should be upgrated. Somehow I would need to draw the text again on it, without strokewidth:
convert -background none -fill white -pointsize 100 -stroke red \
-strokewidth 20 label:text stroke.png
#leu's solution almost good, but the positioning of the new text isn't in the good position. My result was that above, and I don't know, where I took a mistake:
My suggestion: combine label:"Some text" with -annotate "Some text". Like this:
#myfont="Arial-Black-Standard"
#myfont="Tahoma"
#offset="-0-0"
#offset="-20-10"
#offset="-30-10"
#offset="-10+10"
myfont="Tahoma"
offset="+10+10"
convert -respect-parentheses \
\( \
-font "${myfont}" \
-pointsize 180 \
-strokewidth 18 \
-fill blue \
-stroke blue \
-background none \
label:"Test text" \
\) \
-gravity center \
-font "${myfont}" \
-pointsize 180 \
-fill white \
-annotate "${offset}" "Test text" \
result${offset}.png
Play with the offset=... variable (also with the point sizes and stroke widths) to get closer to what you want. Here are some of my results:
However, like #MarkSetchell, I do not fully comprehend what you want to achieve. An explanation of what you mean by "outward stroke" that I do understand is missing...
yes: draw the same text onto your pic - maybe by piping output of your command to another convert
convert -background none -fill white -pointsize 100 -stroke red \
-strokewidth 20 label:text png:- \
| convert -fill white -pointsize 100 -stroke none \
-draw 'text 10,82 "text"' - stroke.png
the trick is to correctly place the second string. x-position is half the strokewidth, but y-position seems to be font- and pointsize-dependant. My approach was to first place both strings over each other when strokewidth was set to 0:
convert -background none -fill white -pointsize 100 -stroke red \
-strokewidth 0 label:text png:- \
| convert -fill white -pointsize 100 -stroke none \
-draw 'text 0,72 "text"' - stroke.png
then you have to add half the strokewidth to this y-position as well.
a bit of trial-and-error to get the correct y-position, but it seems to work for any string.
== edit ==
of course, we don't need to do trial-and-error. But instead we can use ImageMagick's power. Just perform the following steps (in this example within Bash):
#!/bin/bash
# read text from command line (or use "Test Text")
text=${1:-"Test Text"}
# strokewidth
sw=20
# pointsize
ps=120
# font
font=Arial
# result file
result="stroke.png"
# do some calc
sw_half=$(expr $sw / 2)
convert -background none -font $font -fill white -pointsize $ps -stroke red -strokewidth $sw label:"$text" $result
convert -background none -font $font -fill white -pointsize $ps -stroke none label:"$text" png:- | composite -geometry +${sw_half}+${sw_half} - $result $result
You can get the list of fonts available on your system by
convert -list font
The idea is the same as above: draw the text twice and draw one onto the other while using an offset of half the strokewidth.
The results all look like the following

Add gradient overlay under a photo label using imagemagick

I'm trying to convert a bunch of photos using imagemagick. However, I hadn't figured out how to overlay an image with gradient and write some text on it. I know the text part though:
convert IMG_8408.jpg \
-font URWChanceryMediumI \
-pointsize 250 \
-draw "gravity south
fill black text 0,40 'Some text stuff here'" \
test.jpg
Is there a way to add a white gradient to the bottom? Note, that the image size may vary.
What I have:
What I want:
I picked the colors so that it's clearly visible what I want to achieve
You can achieve desired output with 3 commands:
a. create the upper part of your image (a solid rectangle with your selected background color):
convert -size 640x200 xc:#A02B2B background.jpg
b. create another image containing the text over a gradient:
convert -size 640x110 gradient:#A02B2B-#126B27 -pointsize 25 -draw "gravity south fill black text 0,40 'Some text stuff here'" text.jpg
c. combine the images to obtain the final output:
montage background.jpg text.jpg -tile 1x2 -geometry +0+0 output.jpg
Note: I modified text creation parameters in step 2 to keep the command short, but you can add back your original settings
Use the following command:
magick -size 640x310 -define gradient:vector="0,107 0,0" gradient:"#a02b2b-#126b27" -flip -gravity south -font script-mt-bold -pointsize 48 -annotate +0+24 "Some text stuff here" output.png

Resources