I have 7 images that I'm trying to concatenate in a 4x2 tiling. They are all the same width, and have roughly the same height, except one that is about twice higher than the others (4th image). I'm trying to make them tile so that the 4th image covers the space of 2 images in the tiling, but what I get is this :
How can I get rid of the whitespace, and make all the images "float" to the top? I don't mind if the bottom images aren't aligned.
Personally, I would favour convert over montage for this. All you need to know is that -append appends the second picture below the first and that +append appends the second picture to the right of the first.
So, I effectively put 5 below 1 to make a single taller picture, 6 below 2 to make another single taller picture and then 6 & 2 to the right of 1 & 5 etc and then finally stuff 4 at the end on the right:
convert -background none \
\( 1.png 5.png -append \) \
\( 2.png 6.png -append \) +append \
\( 3.png 7.png -append \) +append \
4.png +append result.png
If you want spacers between your images you can add them in like this:
convert -background none \( 1.png 5.png -append \) xc:none[10x10] +append \( 2.png 6.png -append \) xc:none[10x10] +append \( 3.png 7.png -append \) xc:none[10x10] +append 4.png +append result.png
Related
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...
I want to make a wrapping image or gif that when composed with a different image will wrap it like the wrapping image.
For example combining these two images:
Would yield this image
I don't want an imagemagick command that does this specific movement of pixels because then it wouldn't be modular.
Here is one way in Imagemagick using the -roll function. But unfortunately it does not use percent. So I have to do a separate computation in IM 6 to convert percent to pixels. In IM 7 it could be done in one command apart from setting the pct overlap and split.
Here I cut the image into 3 sections (33% each, though different amounts could be used). And then roll the middle sections by 33% to the right with wrap around.
IM 6
pct=33
rollx=`convert palmtree.png -format "%[fx:round($pct*w/100)]" info:`
convert palmtree.png \( -clone 0 -gravity north -crop 100%x$pct%+0+0 +repage \) \( -clone 0 -gravity center -crop 100%x$pct%+0+0 +repage -roll +${rollx}+0 \) \( -clone 0 -gravity south -crop 100%x$pct%+0+0 +repage \) -delete 0 -append result.png
IM 7
pct=33
magick palmtree.png -set option:rollx "%[fx:round($pct*w/100)]" \( -clone 0 -gravity north -crop 100%x$pct%+0+0 +repage \) \( -clone 0 -gravity center -crop 100%x$pct%+0+0 +repage -roll +[rollx]+0 \) \( -clone 0 -gravity south -crop 100%x$pct%+0+0 +repage \) -delete 0 -append result.png
If you do not want 33% for all, then change the pct to whatever percent you want for each part and for the roll as desired. If you want to use multiple images, then replace each -clone with the actual image you want.
Currently I'm using this command:
montage IMG*.JPG -tile 3x1 -geometry 150x100+40+40 -background '#000000' triptych.jpg
And it produces an output like this (red lines added):
The problem (as indicated) is that my images have too much space between them, and that makes me sad.
I'm looking to create something that looks more like this, with the border equal all the way around:
I checked the manpage and several online guides, but none of the options that I tried (-mode concatenate, changing the geometry to +40+20) did what I wanted.
How do I get the output that I want using imagemagick?
If you are just making a triptych, you may get on better with convert +append to lay out images in a row with spacers. So, if your images are 1.png, 2.png and 3.png:
convert -background black \
1.png xc:black[10x] 2.png xc:black[10x] 3.png +append \
-bordercolor black -border 10 result.png
The xc:black[10] are just the two spacers that you can set the width of explicitly. Then the three images with spacers are set in a horizontal row, using +append. Finally, at the end, I put a border around the whole lot with -border.
Or, showing how you have full control over all aspects:
convert -background black \
1.png xc:black[15x] 2.png xc:black[5x] 3.png +append \
-bordercolor black -border 40 result.png
As Wayne says in the comments, you can resize all the images to a uniform size too, while they are still separate before the -append, so you can do this to make sure no image is wider than 400 pixels.
convert -background black \
1.png xc:black[10x] 2.png xc:black[10x] 3.png -resize 400x\> +append \
-bordercolor black -border 10 result.png
If you want even more control, you can individually resize the images like this:
convert -background black \
\( 1.png -resize WxH \) xc:black[10x] \
\( 2.png -resize AxB \) xc:black[10x] \
\( 3.png -resize MxN \) +append \
-bordercolor black -border 10 result.png
If you want a vertical triptych, use -append in place of +append and set the spacer height with xc:black[x10] rather than xc:black[10x].
convert -background black \
1.png xc:black[x10] 2.png xc:black[x10] 3.png -append \
-bordercolor black -border 10 result.png
Keywords: triptych, diptych, montage, photographer, photography, photo, spacing, spacer, padding
Another method is doing it in two steps.
montage img-*.png -background '#000' -geometry +20+20 step-1.png # step 1
convert step-1.png -bordercolor '#000' -border 20 step-2.png # step 2
With step 1, you got the green spacing. And with step 2, you got the red spacing
I have an image with a couple of transparent boxes. I need to insert some specific images in to the transparent boxes. I tried several convert commands but couldn't end up with a solution.
I am using Windows 10 and imagemagick is working on my CLI with no issues. Hope someone can point me into the right direction.
Let's say this 500x400 image is your starting image and it has transparent holes in it at 10,10 and 250,250.
Now, let's say you have two Mr Beans, bean1.jpg and bean2.jpg like this:
Let's lay it out on a red background so you can see what is going on. We'll resize bean1.jpg and place him in the area of the top-left transparent hole, then we'll set up bean2.jpg for the bottom-right transparent hole:
convert -size 500x400 xc:red \
\( bean1.jpg -resize 101x101! -geometry +10+10 \) -composite \
\( bean2.jpg -resize 131x131! -geometry +250+250 \) -composite \
result.png
Now let's do that again, but this time, overlay the original image so the Beans peek through it:
convert -size 500x400 xc:red \
\( bean1.jpg -resize 101x101! -geometry +10+10 \) -composite \
\( bean2.jpg -resize 131x131! -geometry +250+250 \) -composite \
image.png -composite result.png
On Windows, you have to change the backslashes into carets, so \( becomes ^( and \) becomes ^).
So I want to create one large image of size 3600x2280 composed of three smaller images. The first should be resized to 1680x1050 and placed in the top left corner. The 2nd needs to be reiszed to 1920x1200 and placed immediately to the right of it (+1680 over). The 3rd image should be resized to 1920x1080 and placed on the bottom right (+1680+1200). The bottom left will just be blank/transparent.
I've tried various commands I've searched for online and think I'm getting somewhat close with something like the following for just two of the three images:
convert -define png:size=3600x2280 \( Photos/DSC05525-original.jpg -resize 1680x1050 \) -geometry +0+0 -composite \( Photos/Sydney-Loftus-Train-Station-original.jpg -resize 1920x1200 \) -geometry +1680+0 -extent 3600x2280 test.png
...but that places the 2nd image over the first (I think because it doesn't know to extend until the very end?). I've tried various combinations of -composite, -gravity and +repage, but can't seem to find a solution.
There are lots of ways of doing this. Choose the one that corresponds best to the way your mind works! I used test images like this:
1.jpg => red
2.jpg => green (lime actually)
3.jpg => blue
Method 1
convert -background none \
1.jpg -resize 1680x1050! \
\( 2.jpg -resize 1920x1200! \) +append \
\( 3.jpg -resize 1920x1080! -gravity east \) -append \
result.png
That says... "Leave all unpainted areas transparent. Resize image 1. Resize image 2 and place it to the right of image 1 (+append). Resize image 3 and align it East. Append that underneath images 1 and 2 (-append)."
Method 2
convert -background none \
\( 2.jpg -resize 1920x1200! \) \
\( 3.jpg -resize 1920x1080! \) -append \
\( 1.jpg -resize 1680x1050! \) +swap +append result.png
That says... "Load and resize image 2. Load and resize image 3. Place image 3 underneath image 2 (-append). Load and resize image 1. Place image 1 before (+swap) image 2 in the image list. Now append the second image in the list to the right of the first (+append)."
Method 3
convert -background none \
1.jpg -resize 1680x1050! -extent 3600x2280 \
\( 2.jpg -resize 1920x1200! -geometry +1680 \) -composite \
\( 3.jpg -resize 1920x1080! -geometry +1680+1200 \) -composite result.png
That says... "Leave any unpainted areas transparent. Load image 1 resize it then extend the canvas to the full output size to accommodate subsequent images. Load image 2, resize, position and splat onto canvas. Load image 3, resize and splat onto canvas."
Method 4
Just for fun, here's a totally different way of thinking about it:
{ convert 1.jpg -resize 1680x1050! miff:- ; \
convert 2.jpg -resize 1920x1200! miff:- ; \
convert -size 1680x1 xc:none miff:- ; \
convert 3.jpg -resize 1920x1080! miff:- ; } |
montage -background none -geometry +0+0 -tile 2x2 miff:- result.png
That says... "Start a compound statement that will load and resize 4 images and send each of them as a MIFF (Magick Image File Format) to a montage command that will put them all together in 2x2 grid (-tile 2x2) with no spaces between them (-geometry +0+0)."