Using ImageMagick to add whitespace to images in bulk - macos

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

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

AutoMerge two images files to one

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

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

ImageMagick: Can I control which instance is used from a multi-resolution .ico file?

We have an in-house tool that does some operations on windows icon files. Turns out that it only really supports the type of .ico files that are generated by ImageMagick. Should be no big deal because we currently use ImageMagick anyway to generate sizes not supplied in the original image. My plan was to always use ImageMagick to generate images, even when the original .ico file contained an image with the correct resolution, to ensure the image was of the correct format.
So far, so good. However in practice this does not seem to work the way I expect it to. Specifically I'm after a 256x256 icon. The original file contains (I believe) a 256x256 version as it looks high res when viewed from the browser. However, the output file from ImageMagick is obviously a low-resolution one scaled up.
The command line I'm using is:
convert.exe orig.ico -background #FFFFFFFFFFFF0101 -compose Copy \
-gravity Center -scale 256x256! -depth 8 temp2.ico
Question: is there some better set of commands to use, which might start from the 256x256 icon?
Your orig.ico file probably contains multiple dimensions. They will also be stored in the output file. This means a dimension of 16x16 will be upscaled to 256x256 and that produces an ugly image. The 256x256 resolution is most likely the first dimension. You can see all the dimensions with the following command:
identify.exe orig.ico
With the command below you can get a specific dimension/image by specifying the index (starts at zero):
convert.exe orig.ico[0] -background #FFFFFFFFFFFF0101 -compose Copy ^
-gravity Center -scale 256x256! -depth 8 temp2.ico
If the 256x256 dimension is the last image you should set the index to -1:
convert.exe orig.ico[-1] -background #FFFFFFFFFFFF0101 -compose Copy ^
-gravity Center -scale 256x256! -depth 8 temp2.ico

“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:

Resources