Skip to content

Instantly share code, notes, and snippets.

@Plasmoxy
Created February 16, 2026 13:19
Show Gist options
  • Select an option

  • Save Plasmoxy/5438e75a9572824ac4a3f9336352f4e2 to your computer and use it in GitHub Desktop.

Select an option

Save Plasmoxy/5438e75a9572824ac4a3f9336352f4e2 to your computer and use it in GitHub Desktop.
#!/bin/bash
# WebP Converter Script for macOS with Recursive Folder Support
# Usage: ./intowebp.sh image.png
# ./intowebp.sh *.png
# ./intowebp.sh folder/
# ./intowebp.sh . (current directory)
# Configuration
QUALITY=80
METHOD=6
# Supported extensions
EXTENSIONS=("bmp" "png" "jpeg" "jpg" "BMP" "PNG" "JPEG" "JPG")
# Colors for output
GREEN='\033[0;32m'
RED='\033[0;31m'
YELLOW='\033[0;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# Check if ImageMagick is installed
if ! command -v magick &> /dev/null; then
echo -e "${RED}Error: ImageMagick is not installed${NC}"
echo "Install with: brew install imagemagick"
exit 1
fi
# Check if arguments provided
if [ $# -eq 0 ]; then
echo "Usage: $0 <files|folders>"
echo ""
echo "Examples:"
echo " $0 image.png # Single file"
echo " $0 *.png # Wildcard"
echo " $0 folder/ # Recursive folder"
echo " $0 assets/ textures/ # Multiple folders"
echo " $0 . # Current directory"
echo ""
echo "Supported formats: .bmp .png .jpeg .jpg"
exit 1
fi
# Counter for statistics
total=0
success=0
failed=0
skipped=0
# Function to convert a single file
convert_file() {
local input="$1"
# Get filename without extension
local filename="${input%.*}"
local extension="${input##*.}"
local output="${filename}.webp"
# Skip if output already exists
if [ -f "$output" ]; then
echo -e "${YELLOW}Skipping${NC} $input (WebP already exists)"
skipped=$((skipped + 1))
return
fi
# Get original file size
local original_size=$(stat -f%z "$input" 2>/dev/null)
# Convert to WebP
echo -n "Converting $input... "
if magick "$input" -strip -quality $QUALITY \
-define webp:method=$METHOD \
-define webp:auto-filter=true \
"$output" 2>/dev/null; then
# Get new file size
local new_size=$(stat -f%z "$output" 2>/dev/null)
# Calculate compression ratio
if [ $original_size -gt 0 ]; then
local reduction=$(( 100 - (new_size * 100 / original_size) ))
# Format sizes for display
if [ $original_size -gt 1048576 ]; then
local orig_mb=$(echo "scale=2; $original_size / 1048576" | bc)
local new_mb=$(echo "scale=2; $new_size / 1048576" | bc)
echo -e "${GREEN}Done${NC} (${orig_mb}MB → ${new_mb}MB, ${reduction}% smaller)"
else
local orig_kb=$(echo "scale=1; $original_size / 1024" | bc)
local new_kb=$(echo "scale=1; $new_size / 1024" | bc)
echo -e "${GREEN}Done${NC} (${orig_kb}KB → ${new_kb}KB, ${reduction}% smaller)"
fi
else
echo -e "${GREEN}Done${NC}"
fi
success=$((success + 1))
else
echo -e "${RED}Failed${NC}"
failed=$((failed + 1))
fi
}
# Function to process directory recursively
process_directory() {
local dir="$1"
echo -e "${BLUE}Scanning directory: $dir${NC}"
# Find all supported image files recursively
for ext in "${EXTENSIONS[@]}"; do
while IFS= read -r -d '' file; do
total=$((total + 1))
convert_file "$file"
done < <(find "$dir" -type f -name "*.${ext}" -print0)
done
}
# Main processing loop
for arg in "$@"; do
if [ -d "$arg" ]; then
# It's a directory - process recursively
process_directory "$arg"
elif [ -f "$arg" ]; then
# It's a file - check if it's a supported format
extension="${arg##*.}"
extension_lower=$(echo "$extension" | tr '[:upper:]' '[:lower:]')
if [[ " ${EXTENSIONS[@],,} " =~ " ${extension_lower} " ]]; then
total=$((total + 1))
convert_file "$arg"
else
echo -e "${YELLOW}Skipping${NC} $arg (unsupported format)"
fi
fi
done
# Print summary
echo ""
echo "=============================="
echo "Conversion Summary:"
echo "=============================="
echo "Total processed: $total"
echo -e "${GREEN}✓ Success: $success${NC}"
if [ $skipped -gt 0 ]; then
echo -e "${YELLOW}⊘ Skipped: $skipped${NC}"
fi
if [ $failed -gt 0 ]; then
echo -e "${RED}✗ Failed: $failed${NC}"
fi
echo "=============================="
# Calculate total savings if successful conversions
if [ $success -gt 0 ]; then
echo -e "${GREEN}Conversion complete!${NC}"
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment