I only run linux at home (with a few windows machines running virtually), most of which are Ubuntu machines, and wanted to document the best way I have found to do this.
Imagemagick, which is an extremely powerful set of tools, is what I decided to use for converting and resizing my images. It's very simple to use some of the basic feature set to accomplish everything that I needed. I then use other standard command line tools for more advanced renaming of my images.
Here's what you'll need
- Computer running linux (My example uses Ubuntu, but other variations may apply)
- Images to modify and scale
Here's what we'll cover
- Imagemagick: Installing
- Imagemagick: Resizing and Renaming
- Linux CLI - Renaming, replacing characters, and archiving files
Here are 10 examples utilizing the imagemagick suite of tools, that I use to manipulate images for my website and for other various tasks...
I'm using the combination of mogrify and convert which are tools part of the Imagemagick suite in the examples shown below. You should be able to quickly complete many different tedious tasks required to manage, modify, and convert your image files with only some slight modifications and tweaking, There is much more that can be done using the tools of Imagemagick, this guide only scratches the surface.
You can also combine some of the commands together in a single line only separated with &&, to keep as a reference for many of your routine tasks.
example:
mkdir -p ~/images/temp && mogrify -resize 260x -path ~/images/temp ~/images/*.png
ImageMagick - Installing:
Installing Imagemagick (Ubuntu/Debian)
Imagemagick was already installed on my laptop but in case you need to install it
sudo apt-get update
sudo apt-get install imagemagick
ImageMagick - Resizing and renaming multiple images in one directory, saving to a new directory:
We start with using mogrify, as this tools helps when we are interested in keeping the same file name across different directories. Unless noted in the more advanced examples, these processes do not modify or change the original image files, but instead create new images into a separate directory.
I tend to use the first three examples commands shown here, more often that others. I then move down to using the linux CLI examples to do more of the advanced renaming of files as needed and then move onto compressing the PNG files for better optimization - How-To: Quickly Compress All PNG Images In A Directory using Linux
Change the file format, keep the same names
I use this command, changing the format from *.jpg to *png with images taken from my camera. I like to keep the original files thus saving to a different directory as shown
mkdir -p <path-and-directory-for-new-images>
mogrify -format <new-file-format> -path <directory-for-new-images> <path-and-directory-of-images-to-convert>*.<file-extension-of-images-to-convert>
- -p - will not create an error if directory already exists
- -format <new-file-format> - will convert images to this format
- -path <path-and-directory-for-new-images> - will put new images here
example: will change myimage.jpg to converted/myimage.png
mkdir -p ~/images/converted
mogrify -format png -path ~/images/converted ~/images/*.jpg
Resize the width, keep the same names
I then change the widths (while keeping the orginal aspect ratio) of my newly converted images (jpg to png) using the command above, and save these new resized images to yet another new directory
mkdir -p <path-and-directory-for-new-images>
mogrify -resize <width>x -path <directory-for-new-images> <path-and-directory-of-images-to-convert>*.<file-extension-of-images-to-convert>
- -p - will not create an error if directory already exists
- -resize <width>x - auto changes the height proportional
- -path <path-and-directory-for-new-images> - will put new images here
example: will change myimage.png to converted/myimage.png (and scale the size of the image, based on width)
mkdir -p ~/images/converted/scaled
mogrify -resize 1280x -path ~/images/converted/scaled ~/images/converted/*.png
Resize the width, changing the file format, keep the same names
or you can combine the two examples above into a single command
mkdir -p <path-and-directory-for-new-images>
mogrify -format <new-file-format> -resize <width>x -path <directory-for-new-images> <path-and-directory-of-images-to-convert>*.<file-extension-of-images-to-convert>
- -p - will not create an error if directory already exists
- -format <new-file-format> - will convert images to this format
- -resize <width>x - auto changes the height proportional
- -path <path-and-directory-for-new-images> - will put new images here
example: will change myimage.png to temp/myimage.jpg (and scale the size of the image, based on width)
mkdir -p ~/images/temp
mogrify -format jpg -resize 1280x -path ~/images/temp ~/images/*.png
Resize the height, keep the same names
mkdir -p <path-and-directory-for-new-images>
mogrify -resize x<height> -path <directory-for-new-images> <path-and-directory-of-images-to-convert>*.<file-extension-of-images-to-convert>
- -p - will not create an error if directory already exists
- -resize x<height> - auto changes the width proportional
- -path <path-and-directory-for-new-images> - will put new images here
example: will change myimage.png to temp/myimage.png (and scale the size of the image, based on height)
mkdir -p ~/images/temp
mogrify -resize x200 -path ~/images/temp ~/images/*.png
We know move on to use convert, as this allows a more convenient way to format the new file names. In any of the examples below, you can always specify a new image format to automatically convert as well.
Resize the width, adding a suffix to the same names
mkdir -p <path-and-directory-for-new-images>
convert "<path-and-directory-of-images-to-convert>*.<file-extension-of-images-to-convert>" -resize <width>x -set filename:area "%t<suffix-to-append>" <path-and-directory-for-new-images>'%[filename:area].<file-format>
- -p - will not create an error if directory already exists
- -resize <width>x - auto changes the height proportional
- %t - in "-set filename:area" holds the original file name
- <file-format> - the extension and format of the new images
example: will change myimage.png to temp/myimage_sm.png (and scale the size of the image, based on width)
mkdir -p ~/images/temp
convert "/home/algis/images/*.png" -resize 260x -set filename:area "%t_sm" /home/algis/images/temp/%[filename:area].png
Resize the width, adding a prefix to the same names
mkdir -p <path-and-directory-for-new-images>
convert "<path-and-directory-of-images-to-convert>*.<file-extension-of-images-to-convert>" -resize <width>x -set filename:area "<prefix-to-add>%t" <path-and-directory-for-new-images>'%[filename:area].<file-format>
- -p - will not create an error if directory already exists
- -resize <width>x - auto changes the height proportional
- %t - in "-set filename:area" holds the original file name
- <file-format> - the extension and format of the new images
example: will change myimage.png to temp/vacation_photos_myimage.png (and scale the size of the image, based on width)
mkdir -p ~/images/temp
convert "/home/algis/images/*.png" -resize 260x -set filename:area "vacation_photos_%t" /home/algis/images/temp/%[filename:area].png
Resize the width, adding the actual width x height size to the same names
mkdir -p <path-and-directory-for-new-images>
convert "<path-and-directory-of-images-to-convert>*.<file-extension-of-images-to-convert>" -resize <width>x -set filename:area "%t_%wx%h" <path-and-directory-for-new-images>'%[filename:area].<file-format>
- -p - will not create an error if directory already exists
- -resize <width>x - auto changes the height proportional
- %t - in "-set filename:area" holds the original file name
- %w and %h - will display the width and height of the resized file
- <file-format> - the extension and format of the new images
example: will change myimage.png to temp/myimage_260x120.png (and scale the size of the image, based on width)
mkdir -p ~/images/temp
convert "/home/algis/images/*.png" -resize 260x -set filename:area "%t_%wx%h" /home/algis/images/temp/%[filename:area].png
Resize the width, auto numbering suffixed to the same names
mkdir -p <path-and-directory-for-new-images>
convert "<path-and-directory-of-images-to-convert>*.<file-extension-of-images-to-convert>" -resize <width>x -set filename:area "%t_%p" <path-and-directory-for-new-images>'%[filename:area].<file-format>'
- -p - will not create an error if directory already exists
- -resize <width>x - auto changes the height proportional
- %t - in "-set filename:area" holds the original file name
- %p - will display a number starting with 0
- <file-format> - the extension and format of the new images
example: will change myimage.png to temp/myimage_0.png (and scale the size of the image, based on width)
mkdir -p ~/images/temp
convert "/home/algis/images/*.png" -resize 260x -set filename:area "%t_%p" /home/algis/images/temp/%[filename:area].png
Resize the width, auto numbering with 4 digit prefixed to the same names
mkdir -p <path-and-directory-for-new-images>
convert "<path-and-directory-of-images-to-convert>*.<file-extension-of-images-to-convert>" -resize <width>x -set filename:area "%t" <path-and-directory-for-new-images>'%04d_%[filename:area].<file-format>'
- -p - will not create an error if directory already exists
- -resize <width>x - auto changes the height proportional
- %t - in "-set filename:area" holds the original file name
- %04d - denotes to print a 4 digit number, starting with 0000 (there is a bug, and when using %d with the original filenames, it must be at least 4 digits long)
- <file-format> - the extension and format of the new images
example: will change myimage.png to temp/0000_myimage.png (and scale the size of the image, based on width)
mkdir -p ~/images/temp
convert "/home/algis/images/*.png" -resize 260x -set filename:area "%t" /home/algis/images/temp/%04d_%[filename:area].png
Resize the width, auto numbering with 2 digit suffixed to the new names
mkdir -p <path-and-directory-for-new-images>
convert "<path-and-directory-of-images-to-convert>*.<file-extension-of-images-to-convert>" -resize <width>x "<path-and-directory-for-new-images><new-name>%02d.<file-format>"
- -p - will not create an error if directory already exists
- -resize <width>x - auto changes the height proportional
- %t - in "-set filename:area" holds the original file name
- %02d - denotes to print a 2 digit number, starting with 00
- <file-format> - the extension and format of the new images
example: will change myimage.png to temp/Small_Images_00.png (and scale the size of the image, based on width)
mkdir -p ~/images/temp
convert "/home/algis/images/*.png" -resize 260x "/home/algis/images/temp/Small_Images_%02d.png"
Linux CLI - Renaming and replacing characters
Using the mv command, you can easily rename files and directories. There are other tools such as mmv and rename, but these may not be include in all distributions. We will not be converting or resizing any files at this point. These examples will only manipulate the file names.
Also another thing to remember, although using the mv command, you can easily change the file extension (from *jpg to *png) but this will not be converting the file format, you must use the tools shown in the examples above to convert file formats.
Renaming a single file - this will overwrite the orginal file name
mv "<path-and-orignal-file-to-rename>" "<path-and-new-file>"
example: will change example_image.png to web_article_header_image.png
mv "/home/algis/images/example_image.png" "/home/algis/images/web_article_header_image.png"
Renaming multiple files - this will overwrite the original file names
There are many poor examples showing the mv command with the use of wild cards (*) when renaming multiple files. The mv command does not work this way and you cannot simple use wild cards to rename multiple files. For example
mv "/home/algis/images/*.png" "/home/algis/images/%04d_Image.png"
will not work
If we are to strickly use the mv command (and not rename, mmv, or other commands), we need to create some sort of loop to rename each file individually. This is how I do it with the help of awk.
example: will change myimage.png to examples_00.png
find '/home/algis/images/' -maxdepth 1 -name '*.png' | sort -n | awk 'BEGIN{ x=1 }{printf "mv \"%s\" \"/home/algis/images/examples_%02d.png\"\n", $0, x++ }' | bash
Here we don't have a loop per definition, but instead we pipe line by line each file name into the mv command.
- The command find, locates the *.png files in the path /home/algis/images/ -maxdepth 1 only looks in the current path and not to be recursive
- sort, then logically will sort the files it locates (numeric values)
- awk, then parses that filename and formats a string for the mv command
- We re-write new files as "examples_xx.png", where xx wil be replaced with a 2 digit number starting with 00
- Finally bash, then executes this string
Replacing spaces with an underscore in multiple filenames - this will overwrite the original file names
Spaces in file names can sometimes cause issues with certain programs, and you may want to remove any spaces. We are also not specifying any particular file extension, instead any file in only the current working directory and not any subdirectories, we will replace <space> with an <underscore> any time it appears in a file name.
example: will change my image.png to my_image.png
for f in *\ *; do mv "$f" "${f// /_}"; done
Replacing any character with another character in multiple filenames - this will overwrite the original file names
Using the example above, we can customize it for other character replacing. Here we replace a dash <-> with a colon <:> in all files in the current working directory.
example: will change my-image.png to my:image.png
for f in *-*; do mv "$f" "${f//-/:}"; done
Be sure to optimize all of your images using a lossless compression for png images. You can read more about it in my guide: How-To: Quickly Compress All PNG Images In A Directory using Linux