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
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)
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.
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.
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
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