Search code examples
imagemagickimagemagick-convertmontage

Combine and resize multiple images in a square using 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.


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
    

    enter image description here

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