diff options
author | Benedikt Peetz <benedikt.peetz@b-peetz.de> | 2024-10-04 13:43:23 +0200 |
---|---|---|
committer | Benedikt Peetz <benedikt.peetz@b-peetz.de> | 2024-10-04 13:44:12 +0200 |
commit | e3981b8b3983c83a399d14ef1fa1e956f807c6d3 (patch) | |
tree | 44e14162e4c62f9983e158b36573f137cfe5a1e0 | |
parent | build(.gitignore): Stop ignoring outdated `latex/resources` subdirectory (diff) | |
download | flake-templates-e3981b8b3983c83a399d14ef1fa1e956f807c6d3.tar.gz flake-templates-e3981b8b3983c83a399d14ef1fa1e956f807c6d3.zip |
feat(scripts/optimize_images): Init
-rwxr-xr-x | common/scripts/optimize_images.sh | 123 |
1 files changed, 123 insertions, 0 deletions
diff --git a/common/scripts/optimize_images.sh b/common/scripts/optimize_images.sh new file mode 100755 index 0000000..0f48e4b --- /dev/null +++ b/common/scripts/optimize_images.sh @@ -0,0 +1,123 @@ +#!/usr/bin/env nix +#! nix shell nixpkgs#optipng nixpkgs#jpegoptim nixpkgs#nodePackages.svgo nixpkgs#dash --command dash +# shellcheck shell=dash + +# source: https://github.com/stride-tasks/stride/blob/148d513297c8ae66d79fc287769adfe5e711c93c/scripts/optimize-images + +PROJECT_DIR="$(git rev-parse --show-toplevel)" + +cd "$PROJECT_DIR" || { + echo "No '$PROJECT_DIR' ?!" + exit 1 +} + +PNG_OPITMIZE_COMMAND='optipng --quiet -o7 -preserve' +JPG_OPITMIZE_COMMAND='jpegoptim --quiet --strip-all -m76' +SVG_OPITMIZE_COMMAND='svgo --multipass --quiet --input' + +# The extension is the part after the first dot in the filename: +# +# For example: +# file.png => png +# file.tar.gz => tar.gz +find_files_by_extension() { + wanted_extension="$1" + tmp="$(mktemp)" + + git ls-files --cached --modified --other --exclude-standard --deduplicate | while IFS= read -r file; do + extension="${file#*.}" + if [ "$extension" = "$wanted_extension" ]; then + echo "$file" + else + : + # echo "'$file' with extension: '$extension' does not match filter: '$wanted_extension'" 1>&2 + fi + done >"$tmp" + + echo "$tmp" +} + +size_of() { + du -b "$1" | cut -f1 +} + +bytes_human() { + number="$1" + + numfmt --to=iec-i --suffix=B --format="%9.2f" "$number" +} + +# https://stackoverflow.com/questions/44695878/how-to-calculate-percentage-in-shell-script +# Native POSIX solution using string manipulation (assumes integer inputs). +percent() { + DP="$1" + SDC="$2" + + # Special case when DP is zero. + [ "$DP" = "0" ] && echo "0.00" && return + + # # e.g. round down e.g. round up + # # DP=1 SDC=3 DP=2 SDC=3 + Percent=$((DP * 100000 / SDC + 5)) # Percent=33338 Percent=66671 + Whole=${Percent%???} # Whole=33 Whole=66 + Percent=${Percent#"$Whole"} # Percent=338 Percent=671 + Percent=$Whole.${Percent%?} # Percent=33.33 Percent=66.67 + echo "$Percent" +} + +TOTAL=0 +TOTAL_SAVED=0 + +optimize_files() { + FILTER="$1" + PROGRAM="$2" + + printf "%s" "Processing $FILTER files:" + + FILES="$(find_files_by_extension "$FILTER")" + COUNT=$(wc -l <"$FILES") + + if [ "$COUNT" -eq 0 ]; then + echo " no files found!" + return + fi + + echo "" + + I=1 + + TOTAL_INNER=0 + TOTAL_SAVED_INNER=0 + + while IFS= read -r f; do + printf "%-2s/${COUNT} $f ... " "$I" + + SIZE="$(size_of "$f")" + + $PROGRAM "$f" + + NEW_SIZE="$(size_of "$f")" + DIFF=$((SIZE - NEW_SIZE)) + + echo "saved: $(bytes_human "$DIFF") ($(percent $DIFF "$SIZE")%)" + + TOTAL_INNER=$((TOTAL_INNER + SIZE)) + TOTAL_SAVED_INNER=$((TOTAL_SAVED_INNER + DIFF)) + + I=$((I + 1)) + done <"$FILES" + rm "$FILES" + + echo "Total saved for $FILTER: $(bytes_human "$TOTAL_SAVED_INNER") ($(percent $TOTAL_SAVED_INNER $TOTAL_INNER)%)" + echo "" + + TOTAL=$((TOTAL + TOTAL_INNER)) + TOTAL_SAVED=$((TOTAL_SAVED + TOTAL_SAVED_INNER)) +} + +optimize_files 'png' "$PNG_OPITMIZE_COMMAND" +optimize_files 'jpg' "$JPG_OPITMIZE_COMMAND" +optimize_files 'jpeg' "$JPG_OPITMIZE_COMMAND" +optimize_files 'svg' "$SVG_OPITMIZE_COMMAND" + +echo "Total saved: $(bytes_human "$TOTAL_SAVED") ($(percent $TOTAL_SAVED $TOTAL)%)" |