1
\$\begingroup\$

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.

\$\endgroup\$

1 Answer 1

2
\$\begingroup\$

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:

width=${spec%%[xX]*}

For example if you have 200x300 or 200X300 in spec, width becomes 200. (Do take note of the meaningful names.)

Floating point math in the shell

Unfortunately Bash doesn't do floating point math. It would give you a syntax error if you tried to multiply something by 1.5. On the other hand, if you want to multiply by 1.5, and you don't mind truncating decimal points (as is the case here), you could multiply by 3 and divide by 2.

That is, instead of this:

width=$(bc <<< "$width * 1.5")

You could write:

((width = width * 3 / 2))

Use here strings

Instead of echo ... | cmd, write cmd <<< "...".

\$\endgroup\$
1
  • 2
    \$\begingroup\$ An alternative approach to matching [xX] would be to first downcase the string with expansion: newSize="${2,,}"; width="${newSize%%x*}" etc. \$\endgroup\$ Commented Feb 20, 2019 at 18:59

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.