%

Bash : Convertir et optimiser image jpeg et/ou png

Article publié, le et modifié le
5 minutes de lecture

Cet article contient 982 mots.
Source brute de l'article :
Commit version : beb80d0

Description

Ce script a pour but d’aider très simplement à convertir, mais surtout d’optimiser des images jpg, des images png, afin de gagner en poids de l’image, pour l’intégration de celles-ci dans les sites web. Et donc de réduire le coût de la bande passante !

Ce script bash de conversion et d’optimisation d’images jpeg et png, fonctionne très simplement. Il y a trois options possibles :

  • l’option jpg2jpg dont le but est d’optimiser une image jpeg après une conversion  à une qualité, ayant le ratio 70%.
       Le gain est conséquent, de l’ordre du facteur 3 !
  • l’option jpg2png permet de convertir l’image jpeg en image png, puis d’optimiser  ladite image png.
       Attention, explosion du poids !
  • l’option png2png génère l’optimisation d’image png.

Pour se servir de ce script de conversion et d’optimisation d’image jpeg et/ou d’image png, vous devez veillez à avoir les outils suivants :

  • les outils d’ImageMagick qui fournissent l’outil de conversion : mogrify.
  • la librairie jpeg libjpeg qui fournit l’outil d’optimisation jpeg : jpegtran.
  • l’outil d’optimisation png : pngnq
  • le système de fichier virtuel gvfs-bin qui fournit l’outil gvfs-info.

Bien évidemment, vous devez veiller à ce que vos images à traiter soient de qualité originale, des images ‘sources’ !

Le script : convert_image()

#!/bin/bash
# ./convert_image /name_dir/ options
# options are: 'jpg2jpg', 'jpg2png', 'png2png'

# you need ImageMagick tools, libjpeg (jpegtran), gvfs-bin
#  Convert image jpg

#  1/ jpg to jpg, quality 70 and optimize : option jpg2jpg
#  2/ jpg to png : option jp2png
#  3/ png to optimize png : option png2png

clear

#  define variables needed
declare -a EXTS=( jpg JPG ) # extension accepted

declare -i ARGS=2 # number of arguments accepted declare -i mssg=1 #
to display message declare -i cmptr=0 # compteur declare -a
MIME[1]="image/jpeg" # mime type jpg declare -a
MIME[2]="image/png" # mime type png declare -a option=( jpg2jpg
jpg2png png2png )

IFS=$'n'

#  functions needed !

function convert_image () {

    verify_args $1 $2
    verify_bin

    create_vars_dir $1 $2

    #empty_dir $dir_out
    empty_dir $dir_out2
      
    create_dir $dir_out
    create_dir $dir_out2

     for f in find $1 -type f;
    do
         create_vars_image

         case $mime in
              "${MIME[1]}")
                  
                   case $2 in
                        "${option[0]}")
                             increment
                             jpg2jpg
                             optimize_jpg
                             empty_img_converted $dir_out $ff
                        ;;
                        "${option[1]}")
                             increment
                             jpg2png
                             optimize_png
                        ;;
                        *)
                             exit
                        ;;
                   esac
      
              ;;
      
              "${MIME[2]}")
                   case $2 in
                        "${option[2]}")
                             optimize_png
                        ;;
                        *)
                             exit
                        ;;
                   esac
              ;;

              *)
                   exit
              ;;
         esac

    done

}

function create_dir () {

    if [! -d $1](!_-d_$1)then
         if (( mssg == 1 ))then echo "*** Create directory $1 ***"fi
         mkdir $1;
    fi

}

function create_vars_dir () {

    dir_out=$1"converted/"
    if (( mssg == 1 ))then echo "*** Create variables needed for $2 : dir_out ***"fi
    dir_out2=$1"optim_jpg/"
    if (( mssg == 1 ))then echo "*** Create variables needed for $2 : dir_out2 ***"fi

}

function create_vars_image () {

     dir=dirname $f
     ff=basename $f
    ext=${ff:(-3)};
     name=basename $f .$ext
    #length=${#ff}
    #name=${ff:0:$length-4};
     mime=gvfs-info --attributes="standard::content-type" $f | grep "standard::content-type" | cut -c27-

}

function empty_dir () {

    if [ $1 ]then
         if [-d $1](-d_$1)then
              cd $1
              rm *
              if (( mssg == 1 ))then echo "~~~ Dir $1 empty! ~~~"fi
              cd ..
         fi
    fi

}

function empty_img_converted () {

    if [ $1 ]then
         if [-d $1](-d_$1)then
              if [$2]($2)then
                   unlink $1$2;
                   if (( mssg == 1 ))then echo "=> 3/ Img $ff deleted in dir $1 !"fi
              fi
         fi
    fi

}

function increment () {

    (( cptr++ ))
    if (( mssg == 1 ))then echo "$cptr :: Image $ff { Mime Type: $mime } to convert"fi

}

function jpg2jpg () {

    cp $f $dir_out
    cd $dir_out

    if (( mssg == 1 ))then echo "=> 1/ Convert image $ff to quality 70 ..."fi
    mogrify -quality 70 $ff
             
    cd ".."

}

function jpg2png () {

    if (( mssg == 1 ))then echo "=> Convert image $ff to PNG ..."fi
    mogrify -format png $f

}

function optimize_jpg () {

    if (( mssg == 1 ))then echo "=> 2/ Optimize image $ff with jpegtran ..."fi
    jpegtran -optimize -progressive -perfect -copy all $dir_out$ff > $dir_out2$ff

}

function optimize_png () {

    if (( mssg == 1 ))then echo "=> Deplace image $name.png to optimize-it! ..."fi
    case $mime in
         "${MIME[1]}")
              mv $1$name".png" $dir_out
         ;;
         "${MIME[2]}")
              cp $1$name".png" $dir_out
         ;;
         *)
              exit
         ;;
    esac

    cd $dir_out

    if (( mssg == 1 ))then echo "=> Optimize image $name.png with pngnq ..."fi
    pngnq -vf -s1 "$name.png"
    if (( mssg == 1 ))then echo "=> delete $name.png ..."fi
    unlink "$name.png"
    if (( mssg == 1 ))then echo "=> Rename image PNG temporary in name $name.png ..."fi
    mv "$name-nq8.png" "$name.png"
    #echo "=> Optimize image PNG {$name.png} with optipng ..."
    #optipng -o7 "$name.png"

    cd ".."

}

function status () {

    case $1 in
         0) txt="*** More argument; just call the script as: ./convert_image /name_dir/ 'jpg2jpg|jpg2png|png2png' ***" ;;
         1) txt="*** Directory needed! ***" ;;
         2) txt="*** argument 'jpg2jpg', 'jpg2png' or 'png2png' needed! ***" ;;
         3) txt="*** bad argument: argument is 'jpg2jpg', 'jpg2png' or 'png2png'! ***" ;;
         4) txt="*** ERROR: Script stop here because the bin ***$2*** is not installed; in $3... ***" ;;
    esac

    if test -n "$txt"then echo "$txt"fi

    exit

}

function verify_args () {

    if test -z "$1"then status 1; fi
    if [! -d $1](!_-d_$1)then exit; fi
    if test -z "$2"then status 2; fi
    if (( $2 != "jpg2jpg" || $2 != "jpg2png" || $2 != "png2png" ))then status 3; fi

}

function verify_bin () {

    bin[1]="jpegtran"
    bin[2]="mogrify"
    bin[3]="gvfs-info"
    get[1]="libjpeg"
    get[2]="ImageMagick Tools"
    get[3]="gvfs-bin"
      
    for (( i=1 ; i<=3 ; i++ )) do
         if [[ ! -e "/usr/bin/${bin[$i]}" ]]then status 4 "${bin[$i]}" "${get[$i]}"fi
    done

}

# appel to the function convert_image

if [ $# -ne "$ARGS" ]; then

    status 0

else

    convert_image $1 $2

fi

Utilisation

Il ne reste plus qu’à l’utiliser ainsi :

$ chmod 0700 convert_image $ ./convert_image /name_dir/ option