After a few months of mostly programming I took a step back this month to do regular HTML/CSS coding. At first it was really enjoyable but soon a first problem has arisen: exported images do not often come in the right form. Sometimes it’s PNG while it should have been JPG, sometimes the image has unnecessary whitespace or it has a wrong color. One solution is to start an image GUI editor of choice, change the image and save it. But this has a few downsides. Obviously you have to spend some time clicking around. Maybe with some practice you learn some key combos to do things faster. But still the simple process of opening the image and saving it is something that just takes too much time. And doing changes to multiple images at once is problematic. Chances are, that if you can explain the task in a few words, it is also simple to do in the command line.

The two most fundamental commands

There are a couple command line commands that can help you do most of the basic operations. These are of course for BASH, not Windows CLI. (That generally means you need a MacOS, Linux or Ubuntu on Windows). The library that enables the image processing is mostly ImageMagick. You most likely already have it installed, but on some Linux distributions you might need to install it yourself:

sudo apt-get install imagemagick

Sometimes it also needs to be installed on MacOS. That can easily be done with Brew:

brew update && brew install imagemagick

ImageMagick provides you with two powerful commands: convert and mogrify. Mogrify generally takes the same arguments as convert, but allows you to process multiple images and replace them in place. Therefore it is good habit to backup those images beforehand. This will, for example, resize all images in current folder to 256 * 256.

mogrify -resize 256x256 *.jpg

With convert you can specify a single source and output filename. This will convert the image from PNG to JPG.

convert myimage.png myimage.jpg

Mogrify equivalent for that would be:

mogrify -format jpg *.png

Resizing and aspect ratio

For a lot of people, resizing is by far the most common image transformation.

Both convert and mogrify have the -resize (-r) argument available. It can take values in several formats:

mogrify -resize 50% *.jpg # resize to 50%

mogrify -resize 1024x768 *.jpg # resize, keep original aspect ratio

mogrify -r 1024x768! *.jpg # resize, enforce exact dimensions

mogrify -r 1024 # resize to width of 1024

mogrify -r x768 *.jpg # resize to height of 1024

convert source.jpg -r 1024x768 output.jpg

An alternative solution for resizing can be the sips command which is only available on MacOS. Same as mogrify, it replaces images in place.

sips --resampleWidth 1024 *.jpg

sips --resampleHeight 768 *.jpg

sips -z 768 1024 *.jpg # -z takes height as a first argument

Sips also can do also rotates and flips but generally it is less flexible than ImageMagick. It’s main advantage is that it is installed on MacOS by default.

Cropping with the help of gravity

crop with mogrify and convert is very similar to resize. Default usage may not be totally intuitive though.

convert source.jpg -crop 100x100 output.jpg

If the source image is 1000x1000, it will not output one image, but ten of them. This can be useful, but in real world scenario, what you often need is just one image cropped from the center. That’s where -gravity comes into play:

convert source.jpg -crop 100x100+0+0 -gravity center output.jpg

The +0+0 means y=0, x=0 so that we will get a closest tile from the center (actual center of the image).

If you just need to strip some border from the image, it is more useful to use -shave.

convert source.jpg -shave 10x10 output.jpg #shave 10px from sides

Trimming whitespace

When coding, image with whitespace is hardly ever useful. Such images are harder to position and make responsive. Yet when working with GUI editor, it is very easy to save the image with extra unnoticed whitespace.

Removing whitespace is as easy as

mogrify -trim *.{jpg,png}

Trim is quite safe to use, but it’s a good practice to do a backup before. Some images may not be properly cropped because there can be tiny amount “pixel residue”. It is possible to add -fuzz to make the trim more strict.

mogrify -trim -fuzz 40% *.{jpg,png}

Replacing colors and transparency

Do you need the logo in different color? Or do you need a transparent background? Both of these changes are very easy to do:

convert white.png -fill '#000' -opaque '#fff' black.png

-fuzz can be added here to add tolerance in color replacement

If you have a jpg with white background and need to make it transparent, you can simply do:

convert source.jpg -transparent white output.png

Creating favicons

If the source image is at least 256x256, you can quickly convert into an ico that includes all the necessary standard image versions:

convert source.png -define icon:auto-resize favicon.ico

Getting more done with custom shell scripts

Preparing some shell scripts to automatise common image transformation can be helpful. Those can be more advanced operations or sequence of operations done on multiple images.

What I mean with shell scripts are mostly functions, that are placed in ~/.bashrc file (or ~/.bash_profile on Mac) so they are always available.

I use them often when working with collection of images, mostly galleries. When creating a gallery, when I receive a collection of images I most of the time do

mv_seqnum(){

a=1

for i in $@; do

new=$(printf "%04d.jpg" "$a")

mv -- "$i" "$new"

let a=a+1

done

} # This can be used as $ cd some-image-folder

$ mv_seqnum

This will rename the images to sequential numbers. That makes it easy to work with them in various templating languages and scripts. Next step is to create multiple image sizes for thumbnail and srcset purposes.

img_size_folder(){

mkdir $1

cp *.jpg $1

cd $1

mogrify -r $2 *.jpg

cd ..

} # This can be used as $ cd some-image-folder

$ img_size_folder thumbnail 150

This will create a thumbnail folder, copies the images to it and resizes them to 150px width.

Now we can create a script that will take a collection of images and creates multiple size versions of them:

create_image_sizes(){

mv_seqnum

img_size_folder big 1620

img_size_folder full 1920

img_size_folder medium 1024

img_size_folder small 450

} $ cd some-image-folder

$ create_image_sizes

This will create folders big, full, medium and small and adds images of size 1620px, 1920px, 1024px and 450px width in them.

Compression

Imagemagick also offers several ways to optimize images for lower size. You can use option -quality (with range 0 to 100). And you can also apply many filters via -filter option. You can opt-in for progressive JPEG rendering, extra sharpening and other features.

Advanced techniques for compression are well described in this excellent smashing magazine article, especially the smartresize function can be very handy.

On MacOS it is also possible to ImageOptim-CLI which can provide up to 80% size decreases.

Conclusion

So far these commands served me well and I did not need to open a GUI. And as always, by using CLI you are not only saving time but you are also learning methods that you can later use for automatisation in custom build scripts and integrations. The learning curve is worth it.

— — — — —

I am a Freelancer Developer currently looking for work for upcoming months. I specialise in building single page applications with Ember.js and performance optimisations. Feel free to contact me at malindacz@gmail.com or twitter.com/@martinmalinda.cz