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

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

Related

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

ImageMagick, set relative size in chain of convert operators

I'd need to set the size relative to the size already set. I'd need it because my flow involves defining primitives inside other ones. Eg
convert -size 200x100 xc:black \( -size 30x40% xc:red \) -gravity West -composite out.png
That 30x40% is not working this way, it becomes pixels 30x40. I can achieve this specific goal in the first example by using resize
convert -size 200x100 xc:black \( xc:red -resize 30x40% \) -gravity West -composite out.png
In this second version, xc:red inherits the size 200x100, so -resize works as expected. Though the size of further/inner primitives are not reduced to 60x40, it remains 200x100, so in the third example, the green rectangle has orientation landscape and not portrait
convert -size 200x150 xc:blue \
\( xc:red -resize 50x100% \
\( xc:green -resize 40% \) \
-gravity Center \
-composite \
\) \
-gravity West \
-composite \
out.png
So green area is 80x60 pixels, 40% of 200x150. I'd like to somehow reset the size to the size of xc:red after resize by the time I'm introducing xc:green.
I think you are trying to create canvases whereby each one is a percentage of the the size of the previous one. There may be an easier way, but you could save each canvas (and implicitly its size) in a MPR "Magick Persistent Register" (named lump of RAM) as you create it, then recall the latest one and overwrite it each time you want to do something relative to that:
convert -gravity west -size 200x100 xc:black -write MPR:S \
\( MPR:S -resize 30x40% -fill red -colorize 100 -write MPR:S \) -composite \
\( MPR:S -resize 50x50% -fill blue -colorize 100 -write MPR:S \) -composite \
\( MPR:S -resize 50x50% -fill lime -colorize 100 \) -composite result.png
Alternatively, you could let your bash/POSIX shell do it for you inside an "arithmetic expression":
W=200
H=100
convert -gravity west -size ${W}x${H} xc:black \
\( -size $((W=W*30/100))x$((H=H*40/100)) xc:red \) -composite \
\( -size $((W=W*50/100))x$((H=H*50/100)) xc:blue \) -composite \
result.png
Be aware that the shell only deals with integer maths, so it's not going to end well if you aim for 50% of 25 pixels...

Imagemagick - move/offset images within a tiled montage?

Consider this example (Ubuntu 18.04, ImageMagick 6.9.7-4 Q16 x86_64 20170114):
convert -size 300x100 xc:red red.png
convert -size 100x100 xc:blue blue.png
montage red.png blue.png -frame 5 -geometry '+0+0' -tile 1x redblue.png
This gives the following image:
What I'd like to do, is move the blue square on arbitrary x position "within its tile"; say align left edge of blue square to where 25% of the red rectangle width would be, or at 50% - or even align right edge of blue square with right edge of red rectangle.
I have seen that -tile-offset exists (https://imagemagick.org/script/command-line-options.php#tile-offset), and I've tried it with this example, but it doesn't look like it does anything.
How can I move an image, part of a ImageMagick montage, within its tile?
EDIT: it looks like -tile-offset can only be specified for explicit tile images (not as in -tile 1x, but as in -tile red.png), and:
Tile smaller image over a background with offsets? - ImageMagick
-tile-offset must come before the tiling. It represents a single global offset, not the spacing for the tiling.
Here's an example:
convert -size 300x100 radial-gradient:\#400-\#FAA red.png
convert -size 500x500 xc: -tile-offset +100+40 +size -tile red.png -border 5 -geometry +5+5 -draw "color 0,0 reset" out.png
then out.png is this (click for full image):
... so to clarify - I'd like to know is its possible to move an image within a tile as obtained in montage tile 1x
As suggested in the comment:
convert -background none red.png \( -size 25x xc:none blue.png +append \) -append result.png
Or with 2 different offsets:
convert -background none red.png \
\( -size 25x xc:none blue.png +append \) \
\( -size 50x xc:none blue.png +append \) \
-append result.png
Not sure what your end-goal is, but you can also do this:
convert -gravity east -background none red.png blue.png red.png blue.png -append result.png
Or this:
convert -gravity center -background none red.png blue.png red.png blue.png -append result.png
In ImageMagick 6, another way is to extend the transparent background, then composite the blue image in the center of the bottom half of the extended image.
convert -size 300x100 xc:red -background none -extent 300x200 -size 100x100 xc:blue -geometry +100+100 -composite result.png

Multiple Commands with ImageMagick

I have the following files:
background.jpg
element1.jpg
element2.jpg
I would like to take element1.jpg, resize it to 300x300, place it on background.jpg, and then take element2.jpg, resize it to 400x400 and place it on the background. I would NOT like the background to be resized.
This is my current command. It appears that resize 400x400! is applied to all the previous images in memory (background.jpg and element1.jpg), instead of one specific image.
convert background.jpg -page +0+0 -resize 300x300! element1.jpg -page +0+0 -resize 400x400! element2.jpg -layers flatten output.jpg
Is there a way to accomplish this without creating a tmp folder to save "middle steps" and have it done all in one command? Or, is there a way to use "brackets" to specify which commands to run first?
You can use parentheses to ensure operators only apply to specific images, like this:
convert background.jpg \
\( element1.jpg -resize NNN \) -composite \
\( element2.jpg -resize MMM \) -composite result.jpg
So, if we create 3 test images, all the same size at 600x400 pixels:
convert -size 600x400 xc:red red.png
convert -size 600x400 xc:yellow yellow.png
convert -size 600x400 xc:blue blue.png
We can now individually resize and position them:
convert blue.png \
\( red.png -resize 80x50! \) -geometry +20+100 -composite \
\( yellow.png -resize 200x200! \) -geometry +200+150 -composite result.png

Imagemagick montage, different -extent values for 3 images

I have the following ImageMagick code that makes a poster out of 3 images, and it works well, however I would like to have a different -extent value for each of the 3 images. How would I do this? Any help would be much appreciated.
exec("montage -background black $img_1 $img_2 $img_3 -geometry 390x620+5+5 -gravity center -extent 396x626^ $img_out");
I still don't understand what you are trying to achieve, but I think the following might help you get where you are trying to go - hopefully!
I would tend to use convert rather than montage, so let's create three different size images, red, green and blue
convert -size 120x200 xc:red red.png
convert -size 200x300 xc:lime green.png
convert -size 80x120 xc:blue blue.png
they look like this
Now I try and make a poster, using a different shade of grey background for each "picture" and a different size and hope you can adapt that to your needs:
convert -gravity center \
\( -background gray70 red.png -extent 800x300 \) \
\( -background gray40 green.png -extent 300x300 \) \
\( -background gray10 blue.png -extent 100x300 \) \
+append result.png

Resources