Bash function to produce variants of images at 2X and 3X resolutions

I use ImageMagick to crop image, encapsulate the related code to functions.

Here is the code:

convertc2(){
convert $1 -crop$2 "two.png"
}

converto3(){

Delimeter="placeHolder"

if [[ $2 == *"x"* ]]; then Delimeter="x" else Delimeter="X" fi First="${2%$Delimeter*}" Fourth="${2##*+}"
Lhs="${2%%+*}" Rhs="${2#"$Lhs+"}" Second="${Lhs##*$Delimeter}" Third="${Rhs%+*}"

One=$(echo "scale=0 ;$First * 1.5" | bc)
One=${One%.*} Two=$(echo "$Second * 1.5" | bc) Two=${Two%.*}
Three=$(echo "$Third * 1.5" | bc)
Three=${Three%.*} Four=$(echo "$Fourth * 1.5" | bc) Four=${Four%.*}

Final=$One"X"$Two"+"$Three"+"$Four

echo $Final convert$1 -crop $Final "three.png" }  Usage like this: convertc2 /Users/dengjiangzhou/Desktop/Simulator\ Screen\ Shot\ -\ iPhone\ 8\ -\ 2019-02-20\ at\ 14.39.02.png 300X300+0+0 converto3 /Users/dengjiangzhou/Desktop/Simulator\ Screen\ Shot\ -\ iPhone\ 8\ -\ 2019-02-20\ at\ 14.39.02.png 300X300+0+0  I need the image size of @2X and @3X. So the function converto3  use convertc2 's size and transform to its size. Delimeter="placeHolder" if [[$2 == *"x"* ]]; then
Delimeter="x"
else
Delimeter="X"
fi


I really care about how to improve the above code. The "x" , I may type "X" or "x".

how to use this "${2%$Delimeter*}" insensitive?

And the calculation code in  converto3() is very ugly.

1 Answer

Double-quote variables used as command line arguments

Instead of this:

convert $1 -crop$2 "two.png"


Write like this:

convert "$1" -crop "$2" "two.png"


This is to protect from word splitting and glob expansion.

Double quote... naturally

This is hard to read and confusing:

Final=$One"X"$Two"+"$Three"+"$Four


I suggest to write like this:

Final="${One}X$Two+$Three+$Four"


Use better variable names

It's really hard to make sense of a program that uses variable names like First, Fourth, Second, Lhs, that don't reveal their purpose.

Also, the convention is to use lowercase names, without capitalizing the first letters.

Chopping off characters case insensitively

Instead of detecting if the delimiter is x or X and storing it in a variable, you could use the pattern [xX], for example: