Combine and resize multiple images in a square using ImageMagick - imagemagick

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

Related

ImageMagick add watermark proportionally

I want to add a watermark logo.png to the nature.jpg with ImageMagick, I use the following commands:
magick nature.jpg logo.png -gravity southeast -geometry +10+10 -composite nature-wm.jpg
convert nature.jpg -resize 50% nature-50%.jpg
magick nature-50%.jpg logo.png -gravity southeast -geometry +10+10 -composite nature-50%-wm.jpg
As you can see, the watermark is smaller when adding it to an image which has large width and height, but this is not what I expected, what I expected is that the watermark can always occupy a fixed percentage of the main image, anyone know how to do this?
logo image
original image
Original image with watermark added
50% width and height of the original image(nature-50%.jpg)
nature-50%.jpg with watermark added(the logo in nature-50%.jpg looks bigger than in the original image)
Update
I want to rotate the watermark, but my approach is not what I expected, it's weird
magick nature.jpg -set option:logowidth "%[fx:int(w*0.25)]" \
\( logo.png -resize "%[logowidth]x" -rotate 45 \) \
-gravity southeast -geometry +10+10 -composite result.jpg
I would do that by loading the background, calculating the width of the logo relative to that (here I used 0.25 as my factor), then loading the logo and resizing before compositing:
magick background.jpg -set option:logowidth "%[fx:int(w*0.25)]" \
\( logo.png -resize "%[logowidth]x" \) \
-gravity southeast -geometry +10+10 -composite result.jpg
Regarding changing the transparency, per your comment, you could make the logo 30% opaque like this:
magick background.jpg -set option:logowidth "%[fx:int(w*0.25)]" \( logo.png -resize "%[logowidth]x" -channel A -fx "u*0.3" \) -gravity southeast -geometry +10+10 -composite result.jpg

How to scale and crop a folder of images?

I've been looking at the documentation for imagemagick and looking at examples of scripts others have made, but I haven't been able to get this working.
The goal is to have imagemagick scale, crop, and save (appending the dimensions to the file names) multiple resized images of various aspect ratios.
For example, a folder containing Image1.png and Image2.png would result in:
Image1_1571x2646.png, Image1_1350x2150.png, Image1_1281x2039.png
Image2_1571x2646.png, Image2_1350x2150.png, Image2_1281x2039.png
Visual aid:
The animation above shows the simplest examples: a 1:1 square, a vertical rectangle, and a horizontal rectangle.
The images should scale to fit the longest dimension of the rectangle, and then crop any leftover pixels. The scaling and cropping should be done relative to the image centers.
Here's what I have so far (using macOS Terminal) but it doesn't work:
convert *.png -path /Users/user/Resized \
\( +clone -resize "1571x2646^” -gravity center -crop 1571x2646+0+0 +repage resultimage -write 1571x2646.png +delete \) \
\( +clone -resize "1350x2150^” -gravity center -crop 1350x2150+0+0 +repage resultimage -write 1350x2150.png +delete \) \
-resize "1281x2039^” -gravity center -crop 1281x2039+0+0 +repage resultimage 1281x2039.png
I'm not sure if I should use mogrify or convert, but if I use mogrify clone gives an error. I'm also not sure if multi-line instructions need to be put into a .sh file or something. The ^ denotes the dimension that should take priority (the larger one). I believe -gravity center is supposed to keep scaling and cropping relative to the image centers.
With Imagemagick, you must use convert. Mogrify cannot handle the parenthesis process and clones, nor can it write multiple outputs for a given input. The ^ is the correct way and -gravity center is correct. You will have to loop over each input image. I do not think you can use wild cards to process more than one image at a time with this type of command. I think -path is only for mogrify.
I would write a loop over each of your input images (bash unix syntax):
cd
cd /Users/user/Resized/
list=`ls`
for img in $list; do
name=`convert "$img" -format "%t" info:`
convert "$img" \
\( -clone 0 -resize "1571x2646^" -gravity center -crop 1571x2646+0+0 +repage +write ${name}_1571x2646.png +delete \) \
\( -clone 0 -resize "1350x2150^" -gravity center -crop 1350x2150+0+0 +repage +write ${name}_1350x2150.png +delete \) \
\( -clone 0 -resize "1281x2039^" -gravity center -crop 1281x2039+0+0 +repage +write ${name}_1281x2039.png +delete \) \
null:
done
The above assumes that your input images have no spaces in their names.
I have changed from +clone to -clone 0, since I am not sure if you change aspect ratio from output to output whether that will cause problems. You can try both ways and see which looks best.

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

add image to transparent section

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

ImageMagick : make images of different sizes float to top

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

Resources