misc-scripts/imgtools.sh

76 lines
1.9 KiB
Bash
Executable File

#!/bin/sh
set -euf
dirminsize () {
cleanup() {
trap 'exit' INT HUP QUIT TERM EXIT
rm -f "$tmpjxl7" "$tmpjxl8" "$tmpjxl9" "$tmpwebp"
kill 0
}
tmpwebp=$(mktemp -u -t webp2jxl_XXXX.webp)
tmpjxl7=$(mktemp -u -t webp2jxl_XXXX.jxl)
tmpjxl8=$(mktemp -u -t webp2jxl_XXXX.jxl)
tmpjxl9=$(mktemp -u -t webp2jxl_XXXX.jxl)
trap 'cleanup' INT HUP QUIT TERM EXIT
ext="webp,png,jxl" depth="-maxdepth 1"
while getopts ":e:r" OPT; do
case "$OPT" in
e) ext="$OPTARG" ;;
r) depth="" ;;
*) exit 1 ;;
esac
done
shift $((OPTIND - 1))
exts=$(awk -F ',' -v OFS=' -o ' '{ for(i=1; i<=NF; i++) $i="-iname *." $i; print}' <<-EOF
$ext
EOF
)
while IFS= read -r f; do
[ -z "$f" ] && continue
echo "$f"
vips webpsave "$f" "$tmpwebp" --min-size --lossless &
vips jxlsave "$f" "$tmpjxl7" --lossless --effort 7 &
vips jxlsave "$f" "$tmpjxl8" --lossless --effort 8 &
vips jxlsave "$f" "$tmpjxl9" --lossless --effort 9 &
wait
read -r _ outfile <<-EOF
$(wc -c "$f" "$tmpwebp" "$tmpjxl7" "$tmpjxl8" "$tmpjxl9" | sort -n)
EOF
mv "$outfile" "${f%.*}.${outfile##*.}" || continue
[ "${outfile##*.}" != "${f##*.}" ] && rm "$f" # remove if there are 2
done <<-EOF
$(set -f; find "${1:-.}" -type f $depth $exts)
EOF
}
jxld2q() {
for n; do
case "$n" in
*.*) i=d; d="$n" ;;
*) i=q; q="$n" ;;
esac
[ "$i" = q ] && d="$(printf '0.1 + (100 - %s) * 0.09\n' "$q" | bc)"
[ "$i" = d ] && q="$(printf '100 - ((%s - 0.1) / 0.09)\n' "$d" | bc)"
echo "distance = $d | quality = $q"
done
}
cmd=$1; shift
case "$cmd" in
dirminsize) dirminsize "$@" ;;
jxld2q) jxld2q "$@" ;;
help|-h) cat >&2 <<-EOF
available commands:
* dirminsize - tries to losslessly squeeze out as much size as possible from every file
in the directory by converting to webp/jxl with various efforts
options: -r (recursive) -e <ext1,ext2,...>
* jxld2q $@ - convert to/from jxl distance/quality for each arg
EOF
;;
*) errecho "wrong command. use help or -h for help" ;;
esac