1. Overview

There are occasions when we need to convert an image from one format to another. It could be to reduce the file size or meet specific format requirements for a particular purpose.

In this tutorial, we’ll check how we batch convert a set of files from one format to another.

2. Using the mogrify Command

To convert images from one format to another, we can use the mogrify command. This is an excellent tool from ImageMagick for all our image manipulation needs. Apart from format conversions, it also supports cropping, resizing, blurring, flipping, joining, and many more operations on image files.

The usage is:

mogrify [options] input-file

Let’s convert PNG files to JPG format:

$ ls
Tracks1.png  Tracks2.png
$ mogrify -format jpg *.png
$ ls
Tracks1.jpg  Tracks1.png  Tracks2.jpg  Tracks2.png
$ file Tracks1.jpg 
Tracks1.jpg: JPEG image data, JFIF standard 1.01, aspect ratio, density 1x1, segment length 16, baseline, precision 8, 800x718, frames 3

As seen above, we’ve got a couple of PNG files. Then we ran the mogrify command over them. In that command, we’ve used the -format option to specify the output format as JPG. As a result, we can see the newly created JPG files. Also, by using the file command, we’ve verified that the resulting file is in JPG format.

Typically, the mogrify command edits the files in place. Hence, it is always recommended to backup the existing files before running this command.

3. Using the convert Command

Similar to the mogrify command, the convert command also supports different image processing techniques. This is yet another tool from ImageMagick.

While the mogrify command edits the files in place, the convert command puts the result in a new file.

Usage is:

convert [input-options] input-file [output-options] output-file

Let’s see this command in action:

$ convert *.png Tracks.jpg
$ ls
Tracks-0.jpg  Tracks-1.jpg  Tracks1.png  Tracks2.png
$ file Tracks-0.jpg 
Tracks-0.jpg: JPEG image data, JFIF standard 1.01, aspect ratio, density 1x1, segment length 16, baseline, precision 8, 800x718, frames 3

In the above command, we took all the PNG files as input. And for the output, we’ve mentioned a filename with a jpg extension. With this, it’ll create new JPG files with Tracks as prefix and a number starting from zero as the suffix.

As a result, we can see the newly created JPG files with different filenames. And using the file command, we’ve confirmed that the newly generated files are in JPG format.

From the fact that the mogrify command edits the files in place, it is more efficient and better suited for batch processing.

On the other hand, the convert command reads all files in the input to memory and does the processing. Thus, if we’re running the command from a directory with lots of files, it can cause memory issues.

However, the convert command is more versatile in allowing us to specify a different destination or filename for the output. Furthermore, it is better for handling multiple images for composition and animations.

3.1. Converting to GIF Format

If we use the above command to convert the image file to GIF format, it’ll take all the PNG files in the folder and create a single GIF file. For most of the scenarios, this is expected. But sometimes, we might need to convert each PNG file to a separate GIF file.

With this, we’ll also see the name mangling capability of the convert command, which is essential during a batch operation.

Let’s check that:

$ convert *.png -set filename:fn '%t' +adjoin '%[filename:fn].gif'
$ ls
Tracks1.gif  Tracks1.png  Tracks2.gif  Tracks2.png
$ file Tracks1.gif 
Tracks1.gif: GIF image data, version 89a, 800 x 718

As we can see in the above results, it has created separate GIF files.

Let’s check the different options we’ve used:

  • -set: to specify a setting
  • filename: we’re doing a filename setting. This is finally used to create the output filename
  • fn: a label for identification
  • %t: this stands for the filename without extension
  • +adjoin: this option creates a separate filename for each input file
  • %[filename:fn].gif: this is the percent escape to generate the final GIF filename

So far, we’ve seen the different ways to use either the mogrify command or the convert command to change the format. If we combine these with other commands in Linux, it will become more flexible in handling files. Also, using the Bash commands save us some time from learning the intricacies of the convert command.

Let’s quickly look at a few of them.

3.2. Using the for Loop

Let’s check how we can do a batch conversion using the for loop:

$ for f in *.png ; do convert "$f"  "${f%.*}.jpg" ; done
$ ls
Tracks1.jpg  Tracks1.png  Tracks2.jpg  Tracks2.png

In the above command, we’ve iterated through all the PNG files. Then we passed the files one by one to the convert command. Finally, we got all the files converted to JPG format.

3.3. Using the ls Command

We can execute batch conversion using the ls command in combination with the xargs command.

Let’s take a look at it:

$ ls -1 *.png | xargs -n 1 bash -c 'convert $0 "${0%.*}.jpg"'
$ ls
Tracks1.jpg  Tracks1.png  Tracks2.jpg  Tracks2.png

We can see the JPG files are created properly from the above results.

3.4. Using the find Command

Next, let’s check how we can use the find command:

$ find . -name '*.png' | xargs -n 1 bash -c 'convert $0 "${0%.*}.jpg"'
$ ls
Tracks1.jpg  Tracks1.png  Tracks2.jpg  Tracks2.png

This is very similar to the above command. Instead of the ls command, we’ve used the find command to pick up the files.

3.5. Using the parallel Command

Whenever we’ve to execute something in batch, the parallel command comes in handy.

$ ls -1 *.png | parallel convert '{}' '{.}.jpg'
$ ls
Tracks1.jpg  Tracks1.png  Tracks2.jpg  Tracks2.png

Here also, we can see the newly created JPG files.

4. Using FFMpeg

Finally, let’s use FFMpeg for converting PNG files to JPG format. As we know, the FFMpeg is used for performing various multimedia tasks. Using this, we can convert images from one format to another.

Let’s run it:

$ for i in *.png ; do ffmpeg -i "$i" "${i%.*}.jpg" ; done
$ ls
Tracks1.jpg  Tracks1.png  Tracks2.jpg  Tracks2.png
$ file Tracks1.jpg 
Tracks1.jpg: JPEG image data, baseline, precision 8, 800x718, frames 3

Here, we’ve used a for loop to iterate through the files. Then, we’ve passed the files one by one to the ffmpeg command. Finally, the ffmpeg command converts them to JPG format since we’ve given jpg as the output filename extension.

5. Conclusion

In this tutorial, we’ve seen the different ways to batch convert image files from one format to another.

As we’ve seen, the convert command can handle all the required conversions. Combining this with the Bash commands gives us more control over the conversion process.

Authors Bottom

If you have a few years of experience in the Linux ecosystem, and you’re interested in sharing that experience with the community, have a look at our Contribution Guidelines.

Comments are closed on this article!