aboutsummaryrefslogtreecommitdiffstats
path: root/tools/optimize_images.sh
diff options
context:
space:
mode:
authorsillylaird <sillyfanboy@gmail.com>2026-09-03 00:33:59 +0000
committersillylaird <sillyfanboy@gmail.com>2026-09-03 00:33:59 +0000
commit898b52edcb47bcb3e9d6106e74ca73e74ea01e70 (patch)
tree85c6ee5ad58b860144551184d4cf86b560c62b91 /tools/optimize_images.sh
downloadwww-898b52edcb47bcb3e9d6106e74ca73e74ea01e70.tar.gz
www-898b52edcb47bcb3e9d6106e74ca73e74ea01e70.zip
import live www.sillylaird.ca webrootHEADmain
Diffstat (limited to 'tools/optimize_images.sh')
-rwxr-xr-xtools/optimize_images.sh93
1 files changed, 93 insertions, 0 deletions
diff --git a/tools/optimize_images.sh b/tools/optimize_images.sh
new file mode 100755
index 0000000..6538448
--- /dev/null
+++ b/tools/optimize_images.sh
@@ -0,0 +1,93 @@
+#!/usr/bin/env bash
+# Optimize site images in place. Lossy but visually conservative.
+#
+# - JPEG : strip metadata, progressive, quality 82
+# - PNG : strip metadata, max zlib recompression (lossless)
+# - GIF : gifsicle -O3 (lossless frame optimization); --lossy on big ones
+# - A short list of oversized tile PNGs is downscaled to a sane max width,
+# since the layout never displays them larger than ~320px.
+#
+# Originals are tarred to "$BACKUP_DIR" before anything is touched.
+# Re-running is safe: already-small files are left alone.
+#
+# Env:
+# BACKUP_DIR where to write the pre-run tarball (default /tmp)
+# DRY_RUN=1 print what would change, touch nothing
+set -u
+cd "$(dirname "$0")/.."
+ROOT="$(pwd)"
+BACKUP_DIR="${BACKUP_DIR:-/tmp}"
+DRY="${DRY_RUN:-0}"
+
+have() { command -v "$1" >/dev/null 2>&1; }
+have convert || { echo "need ImageMagick (convert)"; exit 1; }
+
+# Tile PNGs the layout caps at ~320px wide; 640 keeps a 2x retina buffer.
+# Section heroes are capped wider (display size rarely exceeds ~960px).
+declare -A MAXW=(
+ [assets/img/runescape.png]=640
+ [assets/img/soldierfront.png]=640
+ [assets/img/multibox.png]=640
+ [assets/img/stepmania.png]=640
+ [startpage/videogame.jpg]=720
+ [computers/laptop-compaq.jpg]=960
+ [gaming/runescape/runescape.png]=640
+)
+
+fmt() { numfmt --to=iec "$1" 2>/dev/null || echo "$1"; }
+size() { stat -c%s "$1"; }
+
+if [ "$DRY" != "1" ]; then
+ ts="$(date +%Y%m%d-%H%M%S)"
+ tar -czf "$BACKUP_DIR/images-pre-optimize-$ts.tar.gz" \
+ assets/img images startpage computers gaming vblog mstartpage 2>/dev/null \
+ && echo "backup: $BACKUP_DIR/images-pre-optimize-$ts.tar.gz"
+fi
+
+total_before=0; total_after=0
+process() {
+ local f="$1" before after; before="$(size "$f")"; total_before=$((total_before+before))
+ local tmp="$f.opt.$$"
+ local fl
+ fl="$(printf '%s' "$f" | tr '[:upper:]' '[:lower:]')"
+ case "$fl" in
+ *.jpg|*.jpeg)
+ convert "$f" -strip -interlace Plane -quality 82 "$tmp" 2>/dev/null ;;
+ *.png)
+ local w="${MAXW[$f]:-}"
+ [ -z "$w" ] && w="${MAXW[$fl]:-}"
+ if [ -n "$w" ]; then
+ convert "$f" -strip -resize "${w}x${w}>" -define png:compression-level=9 -define png:compression-filter=5 "$tmp" 2>/dev/null
+ else
+ convert "$f" -strip -define png:compression-level=9 -define png:compression-filter=5 "$tmp" 2>/dev/null
+ fi ;;
+ *.gif)
+ if ! have gifsicle; then total_after=$((total_after+before)); return; fi
+ if [ "$before" -gt 400000 ]; then
+ gifsicle -O3 --lossy=60 "$f" -o "$tmp" 2>/dev/null
+ else
+ gifsicle -O3 "$f" -o "$tmp" 2>/dev/null
+ fi ;;
+ *) total_after=$((total_after+before)); return ;;
+ esac
+ if [ ! -s "$tmp" ]; then rm -f "$tmp"; total_after=$((total_after+before)); return; fi
+ after="$(size "$tmp")"
+ if [ "$after" -lt "$before" ]; then
+ if [ "$DRY" = "1" ]; then
+ printf ' %-40s %8s -> %8s\n' "$f" "$(fmt "$before")" "$(fmt "$after")"; rm -f "$tmp"
+ else
+ mv "$tmp" "$f"
+ fi
+ total_after=$((total_after+after))
+ else
+ rm -f "$tmp"; total_after=$((total_after+before))
+ fi
+}
+
+while IFS= read -r -d '' f; do process "$f"; done < <(
+ find assets/img images startpage computers gaming vblog mstartpage \
+ -type f \( -iname '*.jpg' -o -iname '*.jpeg' \
+ -o -iname '*.png' -o -iname '*.gif' \) -print0 2>/dev/null
+)
+
+echo "total: $(fmt "$total_before") -> $(fmt "$total_after")"