Dumb Shell Tricks no.2 Imagemagick
Created //
Imagemagick
If you do any image manipulation on the command line, you'll want to use ImageMagick.
That means: format conversion, cropping, resizing, stripping metadata (exif), etc.
It's your swiss army knife for image manipulation. It's not a new tool -- it's a solid utility that's been around for 30+ years.
Installation
On MacOS, it's easiest with homebrew. (And if you don't have homebrew installed, you definitely should! For linux people, think of it as apt-get
for MacOS.)
$ brew install imagemagick
Documentation
You can find the ImageMagick documentation here. However, note that the example program name shown there is "magick". Depending on the version you install, it may be "convert" or it may be "magick".
Everything here will use "convert". If you have "magick", just replace "convert" with "magick".
My use cases
Convert png files to webp
$ convert image.png image.webp
It's that simple. Let's say you wanted to convert to jpeg instead:
$ convert image.png image.jpg
It handles pretty much any image format you can think of if.
It'll also do PDF as well, but there are some extra nuances to consider there such as flattening the image, and properly setting the DPI so the quality is good.
Convert png files to webp, and change the compression quality to 80%
$ convert -quality 80 image.png image.webp
Strip the exif data from a JPG file
E.g., strip the EXIF and other metadata, to reduce the file size without affecting the quality.
$ convert -strip image.jpg image-without-metadata.jpg
Convert a folder of png files to webp
This uses a linux "for loop" to iterate over all the png files in the current directory, and convert them to webp.
$ for file in *.png; do convert "$file" "${file%.png}.webp"; done
Show the entire metadata for an image
$ identify -verbose image.webp
You'll get something like this...
Image:
Filename: image.jpg
Permissions: rw-r--r--
Format: WEBP (WebP Image Format)
Mime type: image/webp
Class: DirectClass
Geometry: 896x896+0+0
Units: Undefined
Colorspace: sRGB
Type: TrueColor
Base type: Undefined
Endianness: Undefined
Depth: 8-bit
Channels: 3.0
Channel depth:
Red: 8-bit
Green: 8-bit
Blue: 8-bit
Channel statistics:
Pixels: 802816
Red:
min: 0 (0)
max: 250 (0.980392)
...
Show just the EXIF metadata for an image
$ identify -format "%[EXIF:*]" image.jpg
You'll get something like this...
exif:ApertureValue=17/10
exif:BrightnessValue=74/25
exif:ComponentsConfiguration=...
exif:Contrast=0
exif:CustomRendered=1
exif:DateTime=2020:06:28 13:24:50
exif:DateTimeDigitized=2020:06:28 13:24:50
exif:DateTimeOriginal=2020:06:28 13:24:50
exif:DigitalZoomRatio=0/1
exif:ExifOffset=210
...
Or, instead of having to remember that command, you could just filter the results with grep.
$ identify -verbose image.jpg | grep exif
Find the width and height of an image
$ identify -format "%wx%h" image.jpg
You'll get something like this:
4032x3024
Or, just use identify
without any options, and pick out the width and height from the output:
$ identify image.jpg
The output will be something like:
image.jpg JPEG 4032x3024 4032x3024+0+0 8-bit sRGB 4.90978MiB 0.000u 0:00.000
Resize an image and maintain the current aspect ratio
Let's say we have an image, and we want to resize it down so it's only 600px wide (but maintain the correct proportional height).
$ convert image.jpg -resize 600 image-600px-wide.jpg
Automate generating thumbnail images for a folder
Assume my source images are in a folder named ~/images/source
.
Assume I want the thumbnails to be in a folder named ~/images/thumbnails
.
I want the thumbnails to all be 100px wide. I want the filename and type to stay the same.
Assuming both of these folders exist...
$ cd ~/images/source
$ for file in *.jpg; do convert "${file}" -resize 100 ~/images/thumbnails/"${file}"; done
If I want the file type to change (e.g., to webp), we just have to make a small change.
$ cd ~/images/source
$ for file in *.jpg; do convert "${file}" -resize 100 ~/images/thumbnails/"${file%.jpg}.webp"; done
Resize the image to a square, and keep the aspect ratio, and fill the background with black
In this case, it doesn't matter if my original image is portrait or landscape, it's going to be resized to fit into a 100x100px square correctly.
$ convert image.jpg -resize 100x100 -background black -gravity center -extent 100x100 image-100x100.jpg
We can do the same thing for a folder of images like before. Assume the source images are in ~/images/source
, and the thumbnails should go in ~/images/thumbnails
:
$ cd ~/images/source
$ for file in *.jpg; do convert "${file}" -resize 100x100 -background black -gravity center -extent 100x100 ~/images/thumbnails/"${file}"; done
And that's it for now...
Again, short and sweet. Definitely learn imagemagick -- batch automation of image conversion is fantastic!
As for learning the shell, there are lots of resources available online.
// ka