#!/bin/bash
# 2022-02-10
checkComment () {
comment=`identify -format %c "$1" 2> /dev/null`
if [ $? -ne 0 ]; then
return 99
fi
# echo "Commnet: ${comment}"
if [ "${comment}" = "MZJ" ]; then
echo "Already compressed: $1" 1>&2
return 1
fi
return 0
}
switchArg () {
# echo $1
if [ ! -e "$1" ]; then
echo "Not exists: $1" 1>&2
return
fi
if [ -L "$1" ]; then
echo "Symlink: ${1}" 1>&2
return
fi
if [ -d "$1" ]; then
# echo dir
IFS=$'\n'
for line in `find "$1"`; do
# echo ${line}
if [ -d ${line} ]; then
# echo "Directory: ${line}"
continue
fi
if [ -L ${line} ]; then
echo "Symlink: ${line}" 1>&2
continue
fi
checkComment ${line}
if [ $? -ne 0 ]; then
# already compressed or not jpeg format
continue
fi
# echo "Compress ${line}"
compress $line
done
else
if [ ! -f "$1" ]; then
echo "Not a file: $1" 1>&2
return
fi
compress $1
fi
}
compress () {
fname=`basename $1`
# 一応 拡張子をチェック
echo ${fname} | grep -i -E '\.jpe?g$' > /dev/null 2>&1
if [ $? -ne 0 ]; then
echo "File name mismatch: ${fname}" 1>&2
return 11
fi
# 圧縮後も圧縮前のディレクトリー構造を維持する
dir=${dst_dir}/`dirname $1`
dir=`readlink -m "${dir}"` # ディレクトリーの正規化
mkdir -p "${dir}"
if [ $? -ne 0 ]; then
echo "Cannot make directory: ${dir}" 1>&2
return 1
fi
outfile=`readlink -m "${dir}/${fname}"`
# echo outfile: ${outfile}
if [ -e $outfile ]; then
echo "Output file exists and was skipped: ${outfile}" 1>&2
return 2
fi
# CMDLINE1=(mozjpeg -copy none "$1")
CMDLINE1=(mozjpeg -copy none)
CMDLINE2=(cjpeg -quality ${quality} -optimize -outfile "${outfile}")
if [ "${width}" != "" ]; then
# echo width ${width}
# 指定したサイズより幅が広い場合に縮小
CMDLINE3=(convert "$1" -resize ${width}x\> -quality 100 -)
else
CMDLINE3=(cat "$1")
fi
"${CMDLINE3[@]}" | "${CMDLINE1[@]}" | "${CMDLINE2[@]}"
if [ $? -ne 0 ]; then
echo "Compression failed: ${outfile}" 1>&2
else
# 圧縮済みのマーク "MZJ" を書き込む
mogrify -set comment "MZJ" "${outfile}"
if [ $? -ne 0 ]; then
echo "Comment 'MZJ' setting failed: ${outfile}" 1>&2
fi
fi
# サイズゼロのファイルは削除
if [ ! -s "${outfile}" ]; then
# echo "FILE SIZE = 0"
trash "${outfile}"
echo "Removed file size was 0: ${outfile}" 1>&2
fi
# echo "Compressed: ${1} => ${outfile}"
echo -n "."
return 0
}
usage () {
echo "Usage:"
echo " jpeg85.sh -d <dest dir> [-w <width>] [-q <quality>] <dir|file...>"
echo " default quality 85"
exit 1
}
main () {
# コマンド引数解析 -d は後ろに値を持つ
width=""
dst_dir=""
quality=85
while getopts d:w:q: OPT ; do
case $OPT in
d) dst_dir=$OPTARG
;;
w) width=$OPTARG
;;
q) quality=$OPTARG
;;
*) usage
;;
esac
done
shift $((OPTIND - 1))
# echo $OPT
# echo $@
if [ "$dst_dir" = "" ]; then
usage
fi
# 圧縮後のファイルを入れるディレクトリーを作成
if [ ! -d $dst_dir ]; then
mkdir -p "${dst_dir}"
if [ $? -ne 0 ]; then
echo "Cannot make directory: ${dst_dir}" 1>&2
exit 1
fi
fi
echo "Destination directory: ${dst_dir}"
# コマンド引数解析後の残りをループ
for arg in $@; do
switchArg $arg
done
}
main $@