Skip to content

Instantly share code, notes, and snippets.

@trkaplan
Created December 12, 2025 15:13
Show Gist options
  • Select an option

  • Save trkaplan/cab5f0c73e7c200f715bec5ea0450723 to your computer and use it in GitHub Desktop.

Select an option

Save trkaplan/cab5f0c73e7c200f715bec5ea0450723 to your computer and use it in GitHub Desktop.
Convert to WebP (Custom Raycast script for macOS) - Converts selected images in Finder to WebP format
#!/bin/bash
set -u
set -o pipefail
# Required parameters:
# @raycast.schemaVersion 1
# @raycast.title Convert to webp
# @raycast.mode silent
# Optional parameters:
# @raycast.icon 🤖
# @raycast.packageName convert-to-webp
# Documentation:
# @raycast.description Converts and compress images to webp
# @raycast.author Tuncay Kaplan
# @raycast.authorURL https://x.com/trkaplan
# Configuration
DEFAULT_QUALITY=70
OUTPUT_DIR_NAME="export_webp"
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# Function to show notifications (disabled in silent mode)
notify() {
# Disabled for silent mode
return 0
}
# Function to check if file is an image
is_image() {
local file="$1"
local extension="${file##*.}"
extension=$(echo "$extension" | tr '[:upper:]' '[:lower:]')
case "$extension" in
jpg|jpeg|png|gif|bmp|tiff|tga|exr|jp2|jpc|j2k|jpf|pgx|pnm|webp)
return 0
;;
*)
return 1
;;
esac
}
# Function to get file count in directory
get_file_count() {
local dir="$1"
if [ -d "$dir" ]; then
find "$dir" -maxdepth 1 -type f | wc -l | tr -d ' '
else
echo "0"
fi
}
# Main conversion function
convert_to_webp() {
local files=("$@")
local converted_count=0
local skipped_count=0
local error_count=0
# Get the first file's directory to determine output location
local base_dir=$(dirname "${files[0]}")
local output_dir="$base_dir/$OUTPUT_DIR_NAME"
# Process each file
for file in "${files[@]}"; do
# Skip if file doesn't exist
if [ ! -f "$file" ]; then
((error_count++))
continue
fi
# Check if it's an image
if ! is_image "$file"; then
((skipped_count++))
continue
fi
local filename=$(basename "$file")
local name="${filename%.*}"
local output_file="$output_dir/${name}.webp"
# Check if output file already exists
local counter=1
while [ -f "$output_file" ]; do
output_file="$output_dir/${name}_${counter}.webp"
((counter++))
done
# Create output directory only when we have an image to convert
if [ ! -d "$output_dir" ]; then
mkdir -p "$output_dir"
fi
# Convert the file
if cwebp -q "$DEFAULT_QUALITY" "$file" -o "$output_file" 2>/dev/null; then
((converted_count++))
else
rm -f "$output_file" # Remove partial file if conversion failed
((error_count++))
fi
done
# Show result in Raycast
local total_files=${#files[@]}
if [ $converted_count -gt 0 ]; then
if [ $skipped_count -gt 0 ] || [ $error_count -gt 0 ]; then
echo "🎨 Exported $converted_count/$total_files files to $OUTPUT_DIR_NAME/"
else
echo "🎨 Exported $converted_count file(s) to $OUTPUT_DIR_NAME/"
fi
elif [ $skipped_count -gt 0 ]; then
echo "⚠️ No images found (skipped $total_files file(s))"
elif [ $error_count -gt 0 ]; then
echo "❌ Failed to convert $total_files file(s)"
fi
}
# Check if cwebp is installed
if ! command -v cwebp &> /dev/null; then
echo "${RED}Error: cwebp is not installed${NC}" >&2
echo "Install with: brew install webp" >&2
exit 1
fi
# Get selected files from Finder
selected_files=$(osascript -e '
tell application "Finder"
set theSelection to selection
if (count of theSelection) is 0 then return ""
set out to ""
repeat with anItem in theSelection
try
set out to out & (POSIX path of (anItem as alias)) & "\n"
end try
end repeat
return out
end tell
' 2>/dev/null)
if [ -z "$selected_files" ]; then
echo "${YELLOW}No files selected in Finder${NC}" >&2
exit 1
fi
# Convert selected files to array
IFS=$'\n' read -d '' -r -a files <<< "$selected_files"
# Ensure we have at least one file
if [ ${#files[@]} -eq 0 ]; then
echo "${RED}Error: No valid files found${NC}" >&2
exit 1
fi
# Run conversion
convert_to_webp "${files[@]}"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment