AutoMerge two images files to one - cmd

I am using Montage command-line tool to merge the two jpg images. The output jpg contains the common strip present in the input jpgs. Below is the command to merge two jpgs:
montage -geometry 500 input1.jpg input2.jpg output.jpg
How can I avoid the common area in the output file?
Is there any other tool available to auto-merge the two images?

In ImageMagick, you can simply append the two images side by side or top/bottom.
convert image1.jpg image2.jpg -append result.jpg
will do top/bottom
convert image1.jpg image2.jpg +append result.jpg
will do left/right.
You can append as many images as you want of different sizes. You can use the -gravity setting to align them as desired. If different sizes, then you will have background regions, which you can control the color by using -background somecolor. If desired, you can resize the images by adding -resize 500 after reading the inputs and before the append.
See http://www.imagemagick.org/Usage/layers/#append

I suspect you are trying to make a panoramic by stitching two images with an area of common overlap.
So, if we start with left.png:
and right.png:
You probably want this:
convert left.png -page +200 right.png -mosaic result.png
Just so you can see what happens if I change the x-offset and also how to add a y-offset:
convert left.png -page +280+30 right.png -mosaic result.png

If you want to do what Mark Setchell is suggesting, then using -page is probably the best method, if you have more than one image to merge and the offsets are different. If you only have on pair of image, you can overlap them using +smush in ImageMagick. It is like +append, but allows either overlap or a gap according to the sign of the argument. Unlike -page, it only shifts in one direction according to +/- smush. Using Mark's images,
convert left.jpg right.jpg +smush -400 result.jpg

Related

Batch Resize Photos While Maintaining the Aspect Ratio AND Fitting to a specific pixel size

I am looking to batch resize pictures to a specific pixel size while maintaining the aspect ratio. Is their a way that the picture aspect can be preserved and the rest of the space can be filled in with white? For example, I resize an image to 200 x 200 and due to preserving the aspect ratio it is changed to 200 x 194. I would like the actual image to remain 200 x 194 and white space to fill in the remaining area to create an image that is 200 x 200 px. Thank you in advance!
You can do that with ImageMagick which is included in most Linux distros and is available for macOS and Windows.
Just in Terminal, or Command Prompt on Windows:
magick input.jpg -background white -resize 200x200 -gravity center -extent 200x200 result.jpg
If you have many files to do, you may be better using ImageMagick's mogrify command, which will do them all in one go for you! So make a new directory called processed for the output files and then use this to process all PNG files in the current directory:
magick mogrify -path processed -background white -resize 200x200 -gravity center -extent 200x200 '*.png'
I don't know if you are on Windows or not, so you may or may not need the single quotes around the filenames at the end of that command. Basically, it determines whether the expansion of the filename list is done by the shell (which has limitations on the number of files), or internally by ImageMagick (which does not).
If you are running anything older than v7, the commands become:
convert input.jpg ...
or
mogrify ...

imagemagick gradient mask file creation

I'm playing with this creative script here: http://www.fmwconcepts.com/imagemagick/transitions/. The plan is to mimic what happens with the script with ffmpeg and generate video with transition effects between pictures. My current understanding is this:
I have two pictures A and B.
I need in between a couple of pictures (say 15) that are partially A and partially B.
To do that I use the composite -compose src-over A.jpg B.jpg mask-n.jpg out.jpg command.
During the process, the mask-n.jpg gets generated automatically that gradually change from all black to all white.
Depends on the mathematically equations, the way the transition effect looks is different.
In one of the example, Fred the author gave this:
convert -size 128x128 gradient: maskfile.jpg
This will generate a image like this:
This is partially black and partially white. For the transition to work, I'll need an all white one and an all black one and a couple of others in between. What's the magical command to do that?
I have re-read your question and I am still not sure I understand, but maybe you want a dark grey to light grey gradient:
convert -size 128x128 gradient:"rgb(40,40,40)-rgb(200,200,200)" greygrad.png
Not sure I understand what you are trying to achieve, but if you want an all black one, use:
convert -size 128x128 xc:black black.jpg
and an all white one:
convert -size 128x128 xc:white white.jpg
and a grey one:
convert -size 128x128 xc:gray40 gray40.jpg
If you want to join them for transitions, use
convert im1.jpg im2.jpg -append result.jpg
or use +append to join side by side instead of above and below.
Consider using PNG instead of JPEG throughout.
Fred tells you how the script works at the bottom of the page you have linked to with some example code.
According to his explanation there is only the one mask images as:
The mask images is gradually made lighter

Using ImageMagick to add whitespace to images in bulk

I have a bunch of images that are rectangular and I need them to be square, i.e. 1000x1000, so I've decided to use ImageMagick to pad the sides of the image with the amount of whitespace necessary to make the image square.
I've found the code from the following link useful (see next paragraph). But this requires me to process each image individually, to set the filename and then the -thumbnail dimensions. How can I use this same process to process an entire folder?
Here's the code and the link to it:
http://imagemagick.org/Usage/thumbnails/#pad
convert -define jpeg:size=200x200 hatching_orig.jpg -thumbnail '100x100>' \
-background white -gravity center -extent 100x100 pad_extent.gif
It is not very clear from your question what you actually have (i.e. how big your images are? what format are they?), nor what you actually want (you only provide an example that doesn't do what you want. But I'll take your question at the face-vale of the title and hope you can work out anything missing from there.
If you want to do ImageMagick in bulk, you either need to use a loop in bash, like this:
#!/bin/bash
for f in *.jpg; do
convert "%f" ...
done
or use IM's mogrify command. That is quite a powerful command, so make a backup of your images before you even think of trying to use it.
Let's assume you want to place all JPEG images in the current directory onto a white 1000x1000 pixel background. You would do this:
mogrify -background white -gravity center -extent 1000x1000 *.jpg
Updated Answer
It should be possible to do the resizing and the white padding in a single ImageMagick command without needing to use SIPS as well, like this if you now want 1200x1200 square images padded with white:
mogrify -background white -gravity center -resize 1200x1200\> -extent 1200x1200 *.jpg

“Diff” an image using ImageMagick

How can I get the difference between two images? I have the original image. Someone has written on an exact duplicate of the original image. Now, I need to compare the original to the written on image and extract just the writing in image format.
Example: I have a picture of a house. Someone took a copy and wrote “Hello!” on the copy. I want to somehow compare the two pictures, remove the house, and be left with an image of the words “Hello!”.
Is this possible with ImageMagick? I know there are ways to get the statistical difference between images, but that is not what I am looking for.
My own favorites are these two:
compare image1 image2 -compose src diff.png
compare image1 image2 -compose src diff.pdf
The only difference between the 2 commands above: the first one shows the visual difference between the two images as a PNG file, the second one as a PDF.
The resulting diff file displays all pixels which are different in red color. The ones which are unchanged appear white.
Short and sweet.
Note, your images need not be the same type. You can even mix JPEG, TIFF, PNG -- under one condition: the images should be of the same size (image dimension in pixels). The output format is determined by the output filename's extension.
Should you, for some reason, need a higher resolution than the default one (72 dpi) -- then just add an appropriate -density parameter:
compare -density 300 image1 image2 -compose src diff.jpeg
Illustrated examples
Here are a few illustrations of results for variations of the above command. Note: the two files compared were even PDF files, so it works with these too (as long as they are 1-pagers)!
Left: Image with text Center: Original image Right: Differences (=text) in red pixels.
compare \
porsche-with-scratch.pdf porsche-original.pdf \
-compose src \
diff-compose-default.pdf
This is the same command I suggested earlier above.
Left: Image with text Center: Original image Right: Differences in 'seagreen' pixels.
compare \
porsche-with-scratch.pdf porsche-original.pdf \
-compose src \
-highlight-color seagreen \
diff-compose-default.pdf
This command adds a parameter to make the difference pixels 'seagreen' instead of the default red.
Left: Image with text Center: Original image Right: Blue diffs (but w. some context background)
l
compare \
porsche-with-scratch.pdf porsche-original.pdf \
-highlight-color blue \
diff-compose-default.pdf
This command removes the -compose src part -- the result is the default behavior of compare which keeps as a lightened background the first one of the 2 diffed images. (This time with added parameter to make the diff pixels appear in blue.)
While compare does a good job for many applications, I found that sometimes I prefer a different approach, particularly when comparing images which are mostly grayscale:
convert '(' file1.png -flatten -grayscale Rec709Luminance ')' \
'(' file2.png -flatten -grayscale Rec709Luminance ')' \
'(' -clone 0-1 -compose darken -composite ')' \
-channel RGB -combine diff.png
The idea is follows: convert both file1.png and file2.png to grayscale. Then trat the first as the red channel of the resulting image, the second as the green channel. The blue channel is formed from these two using the darken compose operator, which essentially means taking the minimum.
So things which are white in both images stay white. Things which are black in both images stay black. Things which are white in the first image but black in the second turn red, and things which are white in the second but black in the first turn green.
The result gives you a nicely color-coded image where you can easily associate green with the first input and red with the second. Here is an example where I'm using this to compare the output from LaTeX against that from KaTeX (before I fixed some bug to make this better):
You can combine the approaches, using compare to see where something changed and then using the above to see in more detail how it changed.
From ImageMagick 6.3.4, you can use -compose ChangeMask (see also "Removing a Known Background" and following sections).
For example, using IM7 and these images stone.png, diamond_ore.png, and netherrack.png:
magick diamond_ore.png stone.png -fuzz 15% -compose ChangeMask -composite diamond_ore_overlay.png gives:
magick netherrack.png \( diamond_ore.png stone.png -fuzz 15% -compose ChangeMask -composite +compose \) -composite nether_diamond_ore.png gives:

Glueing tile images together using imagemagick's montage command without resizing

This seems like it might be a reasonably common question, so I'm going to ask it using as many keywords as I can think of!
I have a bunch of (well, nine) tile jpegs, with standard tile filenames. Each jpeg is 220x175 pixels:
(top row)
tile_1_0_0.jpg
tile_1_1_0.jpg
tile_1_2_0.jpg
(middle row)
tile_1_0_1.jpg
tile_1_1_1.jpg
tile_1_2_1.jpg
(bottom row)
tile_1_0_2.jpg
tile_1_1_2.jpg
tile_1_2_2.jpg
How can I use imagemagick/montage to 'glue' or join them all together to make a single, coherent image? I don't want to resize them at all, so I guess the final image should be 660x525.
That would be montage with no framing, shadowing, bordering, etc - just the nine original images, glued together to make a single jpeg.
I know it should be something along these lines, but I'm struggling with getting the order and sizing right:
montage +frame +shadow +label -tile 3x3 -geometry <options> *.jpg joined.jpg
I was looking to do something similar and ended up here (I guess your "as many keywords as possible" thing worked). Here's what I came up with that worked for me. (geometry and tile adjusted for your needs)
montage -border 0 -geometry 660x -tile 3x3 tile* final.jpg
The files get added to the tiles horizontally, so, for -tile 4x2, the disposition would be:
1 2 3 4
5 6 7 8
The numbers being the relative positions of the filenames in the argument list.
As far as I can tell, tile* will expand alphabetically, so you should either specify your filenames manually, or rename then so that they'll sort appropriately, e.g.:
# top row
tile_r0_c0.jpg
tile_r0_c1.jpg
tile_r0_c2.jpg
# middle row
tile_r1_c0.jpg
tile_r1_c1.jpg
tile_r1_c2.jpg
# bottom row
tile_r2_c0.jpg
tile_r2_c1.jpg
tile_r2_c2.jpg
Dave's solution didn't work for me, so I found a better answer here. Try this:
montage -mode concatenate -tile 3x3 tile*.jpg result.jpg
it also works without the second "3"
montage -mode concatenate -tile 3x tile*.jpg result.jpg
the complete line for Windows users is:
"C:\Program Files\ImageMagick-6.8.0-Q16\montage.exe" -mode concatenate -tile 3x tile*.jpg result.jpg
(change the "6.8.0-Q16" with your own version of ImageMagick, of course)
I personally use this minimal command for such tasks:
montage tile*.jpg -tile 3x3 -geometry +0+0 output.jpg
geometry +0+0 will not add any border and conserve the original size of each image (a very much advised option).

Resources