Chain 2 imagemagick commands - imagemagick

I would like to add a logo and some text to an image.
I can achieve this through the following:
// Add logo
composite -geometry +10+20 logo.png input.jpg \
output_with_logo.jpg
// Add text
convert output_with_logo.jpg -font Arial -pointsize 20 \
-draw "fill black text 20,50 'Test'" \
final.jpg
However I'm wondering if I can chain these 2 commands together so I can work from the same source file at once, instead of saving out staged versions of the image.
I've tried:
convert -font Arial -pointsize 20 \
-draw "fill black text 20,50 'Test'" \
-composite -geometry +10+20 input.jpg logo.png \
final.jpg
However this creates 2 "Test" strings on the image

Like this:
convert input.jpg logo.jpg -geometry +10+20 -composite -font Arial -pointsize 20 -draw "fill black text 20,50 'Test'" final.jpg
Rather than use the composite command which won't let you add text, use the convert command and its -composite operator which does the same thing. So, I am saying:
composite A.jpg B.jpg result.jpg = convert A.jpg B.jpg -composite result.jpg
Then, once you have done the compositing, you can add the text afterwards - exactly as you had it.

Related

Add a tile watermark to a part of the image only

Usually, I add watermark text on documents with something like this:
convert -size 700x360 xc:none -fill "#00000020" -font "Liberation-Sans-Bold" -pointsize 60 \
-gravity NorthWest -draw "text 0,75 \"${3}\"" \
-gravity SouthEast -draw "text 0,75 \"${3}\"" \
miff:- |\
composite -tile - "${1}" "${2}"
It spreads a tile with text over the whole image.
Now I need to add a watermark that excludes a specific area on the document.
My question is:
How to limit "operating area" only to a specific rectangular image region defined as x,y,width,height?
On the other hand: Is it possible and how to exclude a specific rectangular region and spread my tiles only outside of it?
You can do that as follows in Imagemagick by creating a tiled watermark image of the size you want and then compositing over the background image.
Here I create the tile image (mpr:wm) . Then tile it out with a transparent background using -draw "color 0,0 reset". Then I composite that over the background image at the desired upper left corner (+32+32). This is all done in one convert command line without needing to pipe.
In:
in="mandril3.jpg"
out="mandril3_wm.jpg"
text="Testing"
convert -size 64x64 xc:none -fill black \
-font "candice" -pointsize 14 \
-gravity NorthWest -draw "text 0,5 '$text'" \
-gravity SouthEast -draw "text 0,5 '$text'" \
-write mpr:wm +delete \
-size 128x128 xc:none -tile mpr:wm -draw "color 0,0 reset" \
$in +swap -geometry +32+32 \
-compose over -composite \
$out
Out:

Captioning all frames of a gif

I have a simple bash script to caption still images (jpg, png...) but it completely fails when given an animated gif. The error is convert: unable to write pixel cache '/tmp/magick-[random chars]': No space left on device # error/cache.c/WritePixelCachePixels/5854. There are many questions similar to mine, however they use specific coordinates to determine where the text should be placed (at least, I think). My script creates a dynamically sized caption area for the text to be written to. The image is appended to the bottom of the caption area (or the caption area is prepended to the top of the image, however you want to think about it.)
#!/bin/bash
input=$1
caption=$2
output=$3
wd=`convert $input -format "%w" info:`
convert \( -size ${wd}x -background white -gravity north -fill black -font FuturaBT-ExtraBlackCondensed -pointsize $(($wd/17)) \
caption:"$caption" \) \
$input \
-append $output
You can also do this in Imagemagick.
convert anim.gif -coalesce \
-gravity north -background white \
-splice 0x18 -font Arial -pointsize 12 -annotate +0+0 'THIS IS A TEST OF CAPTIONING TEXT' \
-layers Optimize anim3.gif
In Imagemagick you will need to create a text image from your caption and then use -layers composite to apply it to your animation.
Input GIF Animation:
Imagemagick 6 Unix Syntax:
convert \( anim.gif -coalesce \) null: \( -size 100x -background white -gravity north -fill black caption:"THIS IS A TEST OF CAPTIONING TEXT ON AN ANIMATION" \) -compose over -layers composite -layers optimize anim2.gif
For Windows, remove the \s
For Imagemagick 7, change convert to magick.

How to handle multiple elements with imagemagick cli?

We need to put 'information bar's to thousands of image files. For like a week or so i'm trying to learn imagemagick but i just couldn't figure this many elements out so i wanted to ask for a help here.
I get the idea of '-/+append'ing elements and swapping between them but when it comes to 3x3 matrix cells and text/image mixings, i just can't do it. As an example, i can get the 3 rows appended and a column next to it but i can't get to the next step of 'appending 2 more rows together then put them as a column block again' because when i try, all those append gets right or bottom as a whole image.. Well, you will get the idea when you see my brief image below..
magick.exe -size 150x100 -gravity center caption:"txt2" caption:"txt3" caption:"txt4" \
-append -size 94x294 xc:white -border 3 -swap 0,1 \
+append outoutout.jpg
FYI, height/width of rows/columns are there just for example not important.. And here comes MSPaint skills:
You have to create each section separately using parenthesis processing. Then if you want append them appropriately. Alternately, you can create a background image and compose ... -composite each image into its correct location.
Here is an example in ImageMagick using the second method.
Unix Syntax:
magick -size 400x400 xc:white \
\( barn.jpg -crop 400x200+0+0 +repage \) \
-geometry +0+0 -compose over -composite \
\( -size 100x200 xc:white -shave 5x5 -bordercolor black -border 5 \) \
-gravity northwest -geometry +0+200 -compose over -composite \
\( -size 100x200 -background white -gravity center -fill black \
-font Candice label:"Text1\n\nText2\n\nText3" \) \
-gravity northwest -geometry +100+200 -compose over -composite \
\( -size 100x200 -background skyblue -gravity center -fill red \
-font Arial label:"First_line\n\n\nSecond_line" \) \
-gravity northwest -geometry +300+200 -compose over -composite \
result.png
See for example:
parenthesis processing
appending
convert ... -composite

How to concatenate 3 images like a triangle using ImageMagick/GraphicsMagick

I have three images, a.jpg, b.jpg, c.jpg。
I want to concatenate them so they look like the follow:
I want to do this using one command. No tmp files generated.
How can I do this using IM/GM.
Another way in ImageMagick is to use smush rather then append. Smush allows offsets.
Create images:
convert -size 250x250 xc:green green.png
convert -size 250x250 xc:black black.png
convert -size 250x510 xc:red red.png
Now combine them:
convert -background white red.png \
\( green.png black.png -smush 10 \) \
+smush 10 \
result.png
Assuming the images are all the correct sizes, this is probably easiest:
convert -size 10x10 green.png xc:white black.png -append xc:white red.png -reverse +append result.png
That says... "make the size of the little spacers 10x10. Load the green image, then make a white spacer, then load the black image and append them together vertically. Make another white spacer. Load the red image. Reverse the columns of images so the most recently added red column is at the left instead of the right, append the images side-by-side."
I did it this way round (starting with the right side) because GraphicsMagick doesn't offer parentheses.
If the images are not already suitably sized, you would be looking at something more like this - still a single command:
convert -size 10x10 \
\( green.png -resize somehow \) \
xc:white \
\( black.png -resize somehow \) \
-append \
xc:white \
\( red.png -resize somehow \) \
-reverse +append result.png
One other way to do this in ImageMagick is just to composite the 3 images to the proper corners of a white background image.
Create images:
convert -size 250x250 xc:green green.png
convert -size 250x250 xc:black black.png
convert -size 250x510 xc:red red.png
Process:
convert -size 510x510 xc:white \
red.png -gravity northwest -composite \
green.png -gravity northeast -composite \
black.png -gravity southeast -composite \
result.png

Appending a label of variable width to one with a fixed size

I am trying to use an Imagemagick command to create a single-letter text label, give it a shadow, place it on the left side of a fixed-size canvas area, and then append this it another label of fixed height but unknown width. So, the desired result is a single letter on the left side of the final transparent PNG, and another label set about 100px to the right of the origin, e.g. this mockup:
I have all of this working in the following command, except that the shadowed text label is not in a fixed size box (should be 100px by 25px). Here's the result:
I think that what I need to do is to turn off the -trim option somehow, but I'm not sure how to do that. +trim is not a valid option, and +repage doesn't do it.
convert \
\( -background transparent \
\( -gravity west -fill lavender -font Constantia.ttf \
-pointsize 12 label:'x' -trim \
\( +clone -background black -shadow 100x3+0+0 -channel A -level 0,50% \
+channel \) \
+swap +repage -gravity center -composite \) \
-size 100x25 -gravity west \) \
\( -size x25 -fill black -background transparent -font MyriadPro-Semibold.otf \
-pointsize 15 label:'Long legend for x' -gravity west \) \
+append -strip legend_test.png
(The trim option is needed to get the height down to 25px--the shadow operation generates too large a vertical extension otherwise. EDIT: And I guess I was wrong above--even w/o the -trim anywhere in the command, the fixed-size image I'm hoping for doesn't work out.)
Hm, looks like there isn't much of a community for ImageMagick left here. I posted to the ImageMagick phpBB board and was able to put together an answer. Briefly:
The -trim option is not an option that affects every image after it is invoked. Instead, it is essentially a command that executes immediately.
The -extent option can be used to increase or decrease an image to a desired size. Apparently the -size command, which I used in my original code, can only be used to set the initial size of an image, not to change the size of an image that already exists.
Here is the final working command:
convert \
\( -background transparent -extent 100x25 -gravity west \
\( -fill lavender -font Constantia.ttf \
-pointsize 12 label:'x' -trim -extent 100x25 -gravity west \
\( +clone -background black -shadow 100x3+0+0 -channel A -level 0,50% \
+channel \) \
+swap +repage -gravity center -composite \) \
-background transparent -extent x25 \) \
\( -size x25 -fill black -background transparent -font MyriadPro- Semibold.otf \
-pointsize 15 label:'Long legend for x' -gravity west \) \
+append -strip legend_test.png

Resources