Shell script to resize image, convert image format in Linux


How To

All of us download photos from our phones and cameras. Before we e-mail an image or post it to the Web, we may need to resize image or perhaps change the format of image. We can use scripts to perform batch image resize and other tasks using ImageMagick

In this article we will use a script to perform below tasks in bulk

  • change image size
  • convert image format

 

ImageMagick

ImageMagick is a free and open-source software suite for displaying, converting, and editing raster image and vector image files. It can read and write over 200 image file formats.

Before we go to our shell script, I will show some examples related to ImageMagick

 

Convert Image Format

To convert image format we will use covert tool from ImageMagick.

# convert -verbose DSC_0091.JPG DSC_0091.PNG
DSC_0091.JPG JPEG 6016x4000 6016x4000+0+0 8-bit DirectClass 8.574MB 0.230u 0:00.240
DSC_0091.JPG=>DSC_0091.PNG JPEG 6016x4000 6016x4000+0+0 8-bit DirectClass 21.95MB 1.910u 0:01.899

Here we are converting JPG format image to PNG.

 

Resize Image

We can resize an image by specifying the scale percentage or the width and height of the output image. To resize an image by specifying WIDTH or HEIGHT, use this:

# convert -verbose  DSC_0688.JPG -resize 1024x768 DSC_0688_resized.JPG
DSC_0688.JPG JPEG 6016x4000 6016x4000+0+0 8-bit DirectClass 12.83MB 0.270u 0:00.270
DSC_0688.JPG=>DSC_0688_resized.JPG JPEG 6016x4000=>1024x681 1024x681+0+0 8-bit DirectClass 696KB 2.490u 0:00.639

If either WIDTH or HEIGHT is missing, then whatever is missing will be automatically calculated to preserve the image aspect ratio:

# convert -verbose  DSC_0560.JPG -resize 1024x DSC_0560_resized.JPG
DSC_0560.JPG JPEG 6016x4000 6016x4000+0+0 8-bit DirectClass 10.97MB 0.230u 0:00.230
DSC_0560.JPG=>DSC_0560_resized.JPG JPEG 6016x4000=>1024x681 1024x681+0+0 8-bit DirectClass 672KB 1.860u 0:00.479

 

Sample Shell Script

Let us jump to our shell script to resize image in a batch.

The batch_image_resize.sh script accepts these arguments:

  • -source: This specifies the source directory of the images.
  • -dest: This specifies the destination directory of the converted image files. If -dest is not specified, the destination directory will be the same as the source directory.
  • -ext: This specifies the target file format for conversions.
  • -percent: This specifies the percentage of scaling.
  • -scale: This specifies the scaled width and height.
  • Both the -percent and -scale parameters may not appear.
  • The script starts by checking the number of command arguments. Either four, six, or eight parameters are valid.
#!/bin/bash
#Filename: batch_image_resize.sh
#Description: A script for image management

if [ $# -ne 4 -a $# -ne 6 -a $# -ne 8 ];
then
  echo Incorrect number of arguments
  exit 2
fi

while [ $# -ne 0 ];
do

  case $1 in
  -source) shift; source_dir=$1 ; shift ;;
  -scale) shift; scale=$1 ; shift ;;
  -percent) shift; percent=$1 ; shift ;;
  -dest) shift ; dest_dir=$1 ; shift ;;
  -ext) shift ; ext=$1 ; shift ;;
  *) echo Wrong parameters; exit 2 ;;
  esac;

done

for img in `echo $source_dir/*` ;
do
  source_file=$img
  if [[ -n $ext ]];
  then
    dest_file=${img%.*}.$ext
  else
    dest_file=$img
  fi

  if [[ -n $dest_dir ]];
  then
    dest_file=${dest_file##*/}
    dest_file="$dest_dir/$dest_file"
  fi

  if [[ -n $scale ]];
  then
    PARAM="-resize $scale"
  elif [[ -n $percent ]];   then
    PARAM="-resize $percent%"
  fi

  echo Processing file : $source_file
  convert $source_file $PARAM $dest_file

done

Now let us execute the batch_image_rezize.sh script to resize image based on percentage. Before calling the script below is the size of all my images

[root@server1 images]# ls -lSh
total 188M
-rw-r--r--. 1 root root  21M Jan 12 00:53 DSC_0091.PNG
-rw-r--r--. 1 root root  13M Apr 16  2017 DSC_0691.JPG
-rw-r--r--. 1 root root  13M Apr 16  2017 DSC_0688.JPG
-rw-r--r--. 1 root root  12M Apr 16  2017 DSC_0687.JPG
-rw-r--r--. 1 root root  12M Apr 15  2017 DSC_0562.JPG
-rw-r--r--. 1 root root  12M Apr 15  2017 DSC_0559.JPG
-rw-r--r--. 1 root root  12M Apr 15  2017 DSC_0561.JPG
-rw-r--r--. 1 root root  12M Apr 16  2017 DSC_0690.JPG
-rw-r--r--. 1 root root  11M Apr 15  2017 DSC_0573.JPG
-rw-r--r--. 1 root root  11M Apr 15  2017 DSC_0560.JPG
-rw-r--r--. 1 root root 9.7M Apr 14  2017 DSC_0096.JPG
-rw-r--r--. 1 root root 9.5M Apr 14  2017 DSC_0094.JPG
-rw-r--r--. 1 root root 9.5M Apr 16  2017 DSC_0689.JPG
-rw-r--r--. 1 root root 9.3M Apr 14  2017 DSC_0095.JPG
-rw-r--r--. 1 root root 8.2M Apr 14  2017 DSC_0092.JPG
-rw-r--r--. 1 root root 8.2M Apr 14  2017 DSC_0091.JPG
-rw-r--r--. 1 root root 7.8M Apr 14  2017 DSC_0093.JPG

I will create a new directory where I will store my resized images

[root@server1 images]# mkdir /new_dir

Now execute the script to resize image to 80%

[root@server1 images]# /tmp/batch_image_resize.sh -source /images/ -percent 80% -dest /new_dir/
Processing file : /images//DSC_0091.JPG
Processing file : /images//DSC_0091.PNG
Processing file : /images//DSC_0092.JPG
Processing file : /images//DSC_0093.JPG
Processing file : /images//DSC_0094.JPG
Processing file : /images//DSC_0095.JPG
Processing file : /images//DSC_0096.JPG
Processing file : /images//DSC_0559.JPG
Processing file : /images//DSC_0560.JPG
Processing file : /images//DSC_0561.JPG
Processing file : /images//DSC_0562.JPG
Processing file : /images//DSC_0573.JPG
Processing file : /images//DSC_0687.JPG
Processing file : /images//DSC_0688.JPG
Processing file : /images//DSC_0689.JPG
Processing file : /images//DSC_0690.JPG
Processing file : /images//DSC_0691.JPG

Now verify the new size which we see that the size of image is reduced to 80% of the original size.

[root@server1 images]# ls -lSh /new_dir/
total 142M
-rw-r--r--. 1 root root  16M Jan 12 01:02 DSC_0091.PNG
-rw-r--r--. 1 root root 9.5M Jan 12 01:02 DSC_0691.JPG
-rw-r--r--. 1 root root 9.3M Jan 12 01:02 DSC_0688.JPG
-rw-r--r--. 1 root root 9.2M Jan 12 01:02 DSC_0562.JPG
-rw-r--r--. 1 root root 9.1M Jan 12 01:02 DSC_0559.JPG
-rw-r--r--. 1 root root 9.1M Jan 12 01:02 DSC_0561.JPG
-rw-r--r--. 1 root root 9.0M Jan 12 01:02 DSC_0687.JPG
-rw-r--r--. 1 root root 8.7M Jan 12 01:02 DSC_0690.JPG
-rw-r--r--. 1 root root 8.3M Jan 12 01:02 DSC_0573.JPG
-rw-r--r--. 1 root root 8.0M Jan 12 01:02 DSC_0560.JPG
-rw-r--r--. 1 root root 7.5M Jan 12 01:02 DSC_0689.JPG
-rw-r--r--. 1 root root 7.2M Jan 12 01:02 DSC_0096.JPG
-rw-r--r--. 1 root root 7.0M Jan 12 01:02 DSC_0095.JPG
-rw-r--r--. 1 root root 7.0M Jan 12 01:02 DSC_0094.JPG
-rw-r--r--. 1 root root 6.2M Jan 12 01:02 DSC_0092.JPG
-rw-r--r--. 1 root root 6.2M Jan 12 01:02 DSC_0091.JPG
-rw-r--r--. 1 root root 5.9M Jan 12 01:02 DSC_0093.JPG

 

How the script works?

  • The command line is parsed with a while loop and the case statement and values are assigned to appropriate variables.
  • $# is a special variable that contains the number of arguments. The shift command shifts the command arguments one position to the left. With this, every time the shifting happens, we can access the next command argument as $1 rather than using $1, $2, $3, and so on.
  • The case statement is like a switch statement in the C programming language. When a case is matched, the corresponding statements are executed. Each match statement is terminated with ;;. Once all the parameters are parsed into the variables percent, scale, source_dir, ext, and dest_dir, a for loop iterates through each file in the source directory and the file is converted.
  • Several tests are done within the for loop to fine-tune the conversion.
  • If the variable ext is defined (if -ext is given in the command argument), the extension of the destination file is changed from source_file.extension to source_file.$ext.
  • If the -dest parameter is provided, the destination file path is modified by replacing the directory in the source path with the destination directory.
  • If -scale or -percent are specified, the resize parameter (-resize widthx or -resize perc%) is added to the command.

Related searches: linux resize image photo. linux image converter. script to resize image. magick resize. convert resize. imagemagick reduce file size. imagick png compression. batch downsize images. resize jpeg batch. linux convert image format from png to jpg.

 

References:
Shell script to convert Image format and resize image

Deepak Prasad

Deepak Prasad

He is the founder of GoLinuxCloud and brings over a decade of expertise in Linux, Python, Go, Laravel, DevOps, Kubernetes, Git, Shell scripting, OpenShift, AWS, Networking, and Security. With extensive experience, he excels in various domains, from development to DevOps, Networking, and Security, ensuring robust and efficient solutions for diverse projects. You can connect with him on his LinkedIn profile.

Can't find what you're searching for? Let us assist you.

Enter your query below, and we'll provide instant results tailored to your needs.

If my articles on GoLinuxCloud has helped you, kindly consider buying me a coffee as a token of appreciation.

Buy GoLinuxCloud a Coffee

For any other feedbacks or questions you can send mail to admin@golinuxcloud.com

Thank You for your support!!

2 thoughts on “Shell script to resize image, convert image format in Linux”

  1. Thank you for example.

    Modified version with handling white spaces in the file names

    #!/bin/bash
    #Filename: batch_image_resize.sh
    #Description: A script for image management

    if [ $# -ne 4 -a $# -ne 6 -a $# -ne 8 ];
    then
    echo Incorrect number of arguments
    exit 2
    fi

    while [ $# -ne 0 ];
    do

    case $1 in
    -source) shift; source_dir=$1 ; shift ;;
    -scale) shift; scale=$1 ; shift ;;
    -percent) shift; percent=$1 ; shift ;;
    -dest) shift ; dest_dir=$1 ; shift ;;
    -ext) shift ; ext=$1 ; shift ;;
    *) echo Wrong parameters; exit 2 ;;
    esac;

    done

    SAVEIFS=$IFS
    IFS=$(echo -en “\n\b”) # process when path contain spaces
    for img in `echo “$source_dir/*”` ;
    do
    source_file=$img
    if [[ -n $ext ]];
    then
    dest_file=${img%.*}.$ext
    else
    dest_file=$img
    fi

    if [[ -n $dest_dir ]];
    then
    dest_file=${dest_file##*/}
    dest_file=”$dest_dir/$dest_file”
    fi

    if [[ -n $scale ]];
    then
    PARAM=”-resize $scale”
    elif [[ -n $percent ]]; then
    PARAM=”-resize $percent%”
    fi

    echo “Processing file : $source_file”

    # restore $IFS
    IFS=$SAVEIFS
    convert “$source_file” $PARAM -quality 90 “$dest_file”
    IFS=$(echo -en “\n\b”) # process when path contain spaces

    done
    IFS=$SAVEIFS

    Reply

Leave a Comment