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.

asked Feb 20, 2019 at 15:57
\$\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 <<< "...".

answered Feb 20, 2019 at 18:54
\$\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

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.