DEV Community

Kelvin Ng
Kelvin Ng

Posted on • Edited on

2

Convert images to WebP with Raycast

webp converter

The Problem

I use screenshots quite often. The default screenshot format is uncompressed PNG, which can be large, especially when capturing items with an abundance of colors. Sending such multi-megabyte files over the internet becomes inconvenient. There are several workarounds:

  • Compress the PNG using apps available in the App Store
  • Compress the PNG with free CLI tools like PNGQuant
  • Change the default format to JPG using the command defaults write com.apple.screencapture type jpg
  • Convert to WebP using CLI tools like cwebp

Regarding the compression approach, whether it's lossy or lossless, it does reduce a large portion of the file size for images with fewer colors, such as a capture of a text document. However, it isn't as effective on images with many colors, like a scenery photo.

The JPG approach is good for capturing screens with numerous colors, such as photos, but it might produce blurry edges on images with simple colors, like text documents.

WebP is an excellent format. Its modern algorithm offers the following benefits:

  • Superior compression rate compared to JPG and PNG
  • Supports both lossy and lossless compression
  • Works well on images, regardless of color complexity
  • Supports transparency

Currently, Apple doesn't allow WebP as the default capture format. Thus, you'll need to manually convert it using the CLI with desired options in the terminal, which is somewhat cumbersome.

The Solution

This is where Raycast comes in. With Raycast, you can create a script or plugin to use CLI tools and execute it effortlessly. No need for the terminal.

So I wrote a script offers the following features:

  • Retrieves the file paths of selected items in Finder
  • Converts the selected files to WebP
  • Allows the user to specify a compression rate, if desired
  • Provides a default compression rate if none is specified by the user
  • Offers an option for lossless compression

To install the script, download all files in my gist and put them in your Raycast script folder.

Code Logic

  • first retrieve the path of selected files in Finder using Apple Script
#!/usr/bin/osascript
tell application "Finder"
set selectedItems to selection
set itemList to ""
repeat with anItem in selectedItems
set itemList to itemList & POSIX path of (anItem as alias) & "\n"
end repeat
return itemList
end tell
  • then create the bash script for file convertion
#!/bin/bash
# Required parameters:
# @raycast.schemaVersion 1
# @raycast.title WebP Converter
# @raycast.mode silent
# Optional parameters:
# @raycast.icon webp.svg
# @raycast.argument1 {"type": "text", "placeholder": "quality(default 80)", "optional": true}
# Documentation:
# @raycast.description Convert images to WebP format
# check if cwebp installed
if ! command -v /opt/homebrew/bin/cwebp &>/dev/null; then
echo "cwebp not found, install with brew ⚠️"
exit 1
fi
# Fetch selected files in Finder using AppleScript
selected_files=$(osascript get-finder-items.applescript)
# Set Internal Field Separator to newline for loop iteration
IFS=$'\n'
# exit with error if no files select
if [[ ! $selected_files ]]; then
echo "no file selected ⚠️"
exit 1
fi
# set default quality to 80 if user not set the optional param
quality=${1:-"80"}
# Loop through each file
for img in $selected_files; do
# only process specific image types
if ! echo "$img" | grep -iE "^.*(png|jpg|jpeg|bmp|tiff)$" >/dev/null; then
echo "⚠️ error: only support png, jpg, bmp, tiff"
continue
fi
output_file="${img%.*}.webp"
# perform lossless compression if user set the quality to 100
if [[ $quality == "100" ]]; then
opt=(-z 5)
else
opt=(-q $quality)
fi
# array with command and its arguments
cmd=(/opt/homebrew/bin/cwebp -quiet "$img" -o "$output_file" "${opt[@]}")
# execute the command
"${cmd[@]}"
# print results
if [[ ! $? ]]; then
echo "can't convert $img"
exit 1
else
echo "webp created "
fi
done
view raw webp.sh hosted with ❤ by GitHub

Notes:

  • Optional quality argument defaults to 80
  • Initiates lossless compression when the user sets quality to 100
  • Supported image types: JPG, PNG, BMP, TIFF
  • Error handling includes
    • cwebp not found
    • No images selected
    • Errors encountered while executing the cwebp command

More

Check out my Projects
Ping me on Twitter

Top comments (0)

Some comments may only be visible to logged-in visitors. Sign in to view all comments.