From ededc5171864db8c8459cc65ca7fc1cc55dc3946 Mon Sep 17 00:00:00 2001 From: Honney OC Date: Fri, 23 Oct 2026 00:02:17 +0000 Subject: [PATCH] feat: updated and optimized optimize-pictures --- configs/alias_useful.fish | 208 +++++++++++++++++++++++++++++++++++++- 1 file changed, 203 insertions(+), 5 deletions(-) diff --git a/configs/alias_useful.fish b/configs/alias_useful.fish index 7379c93..528b980 100755 --- a/configs/alias_useful.fish +++ b/configs/alias_useful.fish @@ -384,7 +384,7 @@ end function optimize-jpegs if command -q jpegoptim - find . -type f \( -iname '*.jpg' -o -iname '*.jpeg' -o -iname '*.jpe' \) -exec jpegoptim --strip-none {} + + find . -type f \( -iname '*.jpg' -o -iname '*.jpeg' -o -iname '*.jpe' -o -iname '*.jif' -o -iname '*.jfif' -o -iname '*.jfi' \) -exec jpegoptim --strip-none {} + else echo "jpegoptim is not installed. Install it with: sudo pacman -S jpegoptim" end @@ -406,8 +406,206 @@ function optimize-gifs end end -function optimize-pictures - optimize-jpegs - optimize-pngs - optimize-gifs +function optimize-webps + if command -q cwebp + find . -type f -iname '*.webp' -exec sh -c 'for f; do cwebp -lossless -quiet "$f" -o "$f.tmp" && mv "$f.tmp" "$f"; done' sh {} + + else + echo "cwebp is not installed. Install it with: sudo pacman -S libwebp-utils" + end +end + +function optimize-svgs + if command -q svgo + find . -type f -iname '*.svg' -exec svgo {} + + else + echo "svgo is not installed. Install it with: sudo pacman -S svgo" + end +end + +function __opt_size --description "Format a byte count as human-readable" + set -l b $argv[1] + if test $b -ge 1073741824 + printf '%.1fG' (math "$b / 1073741824") + else if test $b -ge 1048576 + printf '%.1fM' (math "$b / 1048576") + else if test $b -ge 1024 + printf '%.1fK' (math "$b / 1024") + else + printf '%dB' $b + end +end + +function optimize-pictures --description "Optimize images in one pass. Flags: --continue resume, -v/--verbose show tool output" + set -l cache_file "$PWD/.optimize-pictures.cache" + set -l state_file "$PWD/.optimize-pictures.state" + set -l rebuild 1 + set -l verbose 0 + + for arg in $argv + switch $arg + case --continue + set rebuild 0 + case --verbose -v + set verbose 1 + end + end + + if test $rebuild -eq 0 + if not test -f "$cache_file" + echo "optimize-pictures: no cache file found at $cache_file" >&2 + return 1 + end + else + find . -type f \( -iname '*.jpg' -o -iname '*.jpeg' -o -iname '*.jpe' -o -iname '*.jif' -o -iname '*.jfif' -o -iname '*.jfi' -o -iname '*.png' -o -iname '*.gif' -o -iname '*.webp' -o -iname '*.svg' \) > "$cache_file" + end + + if not test -s "$cache_file" + echo "optimize-pictures: no images to optimize." + return 0 + end + + set -l remaining_file "$cache_file.tmp" + : > "$remaining_file" + + set -l total (count (cat $cache_file)) + set -l done 0 + set -l saved 0 + set -l original 0 + + if test $rebuild -eq 0 + set -l st (string split ' ' -- (cat "$state_file" 2>/dev/null)) + if test (count $st) -ge 2 + set saved $st[1] + set original $st[2] + end + end + + set -l live 0 + if isatty stdout; and test $verbose -eq 0 + set live 1 + end + + while read -l file + set done (math $done + 1) + set -l ext (string lower -- (string split -r '.' -- $file)[-1]) + set -l before (stat -c%s -- "$file" 2>/dev/null; or echo 0) + set -l ok 1 + + switch $ext + case jpg jpeg jpe jif jfif + if command -q jpegoptim + if test $verbose -eq 1 + jpegoptim --strip-none "$file" + else + jpegoptim --strip-none "$file" >/dev/null 2>&1 + end + set ok $status + else + echo "jpegoptim not installed, skipping: $file" >&2 + end + case png + if command -q oxipng + if test $verbose -eq 1 + oxipng "$file" + else + oxipng "$file" >/dev/null 2>&1 + end + set ok $status + else + echo "oxipng not installed, skipping: $file" >&2 + end + case gif + if command -q gifsicle + if test $verbose -eq 1 + gifsicle -b -O3 "$file" + else + gifsicle -b -O3 "$file" >/dev/null 2>&1 + end + set ok $status + else + echo "gifsicle not installed, skipping: $file" >&2 + end + case webp + if command -q cwebp + if test $verbose -eq 1 + cwebp -lossless "$file" -o "$file.tmp" + else + cwebp -lossless -quiet "$file" -o "$file.tmp" >/dev/null 2>&1 + end + set ok $status + if test $ok -eq 0 + mv "$file.tmp" "$file" + set ok $status + end + else + echo "cwebp not installed, skipping: $file" >&2 + end + case svg + if command -q svgo + if test $verbose -eq 1 + svgo "$file" + else + svgo "$file" >/dev/null 2>&1 + end + set ok $status + else + echo "svgo not installed, skipping: $file" >&2 + end + end + + set original (math $original + $before) + if test $ok -eq 0 + set -l after (stat -c%s -- "$file" 2>/dev/null; or echo 0) + if test $after -lt $before + set saved (math $saved + $before - $after) + end + else + echo "$file" >> "$remaining_file" + end + + echo "$saved $original" > "$state_file" + + set -l pct 0 + if test $original -gt 0 + set pct (math "round($saved * 100 / $original)") + end + + if test $live -eq 1 + printf '\r\033[2K[%d/%d] %s saved %s (%d%%)' $done $total $file (__opt_size $saved) $pct + else if test $verbose -eq 0 + printf '[%d/%d] %s saved %s (%d%%)\n' $done $total $file (__opt_size $saved) $pct + end + end < "$cache_file" + + if test $live -eq 1 + echo + end + + mv "$remaining_file" "$cache_file" + + set -l pct 0 + if test $original -gt 0 + set pct (math "round($saved * 100 / $original)") + end + set -l sz (__opt_size $saved) + + if not test -s "$cache_file" + rm -f "$cache_file" "$state_file" + echo "optimize-pictures: optimized $done images, saved $sz ($pct%)." + else + set -l remaining (count (cat $cache_file)) + echo "optimize-pictures: $remaining images remaining (saved so far: $sz, $pct%). Run 'optimize-pictures --continue' to resume." + end +end + +function install-optimizer --description "Install image optimizer packages (Arch/pacman)" + if not command -q pacman + echo "install-optimizer: pacman not found. This helper is for Arch Linux." >&2 + return 1 + end + set -l pkgs jpegoptim oxipng gifsicle libwebp-utils svgo + if test (count $argv) -gt 0 + set pkgs $argv + end + sudo pacman -S --needed $pkgs end \ No newline at end of file