Last active
August 8, 2026 16:50
-
-
Save jonlabelle/68c37f59bf7f9fd4d1834b7fbf60618f to your computer and use it in GitHub Desktop.
Shortcut for ImageOptim.app tool, lossless image optimizer for MacOS.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/env bash | |
| ## | |
| # Shortcut for ImageOptim.app tool, Lossless image optimizer for MacOS. | |
| # Only files and directories are allowed as arguments. | |
| # | |
| # Example: | |
| # imageoptim /path/to/image.png | |
| # imageoptim /path/to/images | |
| # | |
| # See: https://imageoptim.com/command-line.html | |
| # | |
| # Installation: | |
| # 1. Download and install ImageOptim.app from https://imageoptim.com/mac | |
| # 2. Download this script using curl and make it executable: | |
| # curl -fsSL https://jonlabelle.com/snippets/raw/3529/imageoptim.sh -o imageoptim | |
| # chmod +x imageoptim | |
| # 3. Move it to a directory in your PATH, e.g.: | |
| # mv imageoptim ~/bin/ | |
| # | |
| # Author: Jon LaBelle | |
| # License: MIT | |
| # Date: 2026-02-23 | |
| # | |
| # Snippet: https://jonlabelle.com/snippets/view/shell/imageoptimapp-cli-shortcut | |
| # Gist: https://gist.github.com/jonlabelle/68c37f59bf7f9fd4d1834b7fbf60618f | |
| ## | |
| # Check if ImageOptim.app is installed | |
| if ! [[ -d "/Applications/ImageOptim.app" ]]; then | |
| echo "ImageOptim.app is not installed." | |
| echo "Download it from: https://imageoptim.com/mac" | |
| echo "After installation, run this command again." | |
| exit 1 | |
| fi | |
| # Show help if no arguments are provided or if --help/-h is passed | |
| if [[ "$#" -eq 0 ]] || [[ "$1" == "--help" ]] || [[ "$1" == "-h" ]]; then | |
| cat <<'EOF' | |
| ImageOptim - Lossless image optimizer for macOS | |
| Usage: | |
| imageoptim [options] <file|directory> [<file|directory> ...] | |
| Arguments: | |
| file|directory Image file or directory containing images to optimize | |
| Options: | |
| -p, --preserve-timestamps Preserve file modification timestamps | |
| -h, --help Show this help message | |
| Examples: | |
| imageoptim photo.jpg | |
| imageoptim --preserve-timestamps photo.jpg | |
| imageoptim ~/Pictures | |
| imageoptim image1.png image2.jpg ~/Desktop/images | |
| Dependencies: | |
| ImageOptim.app https://imageoptim.com/mac | |
| EOF | |
| exit 0 | |
| fi | |
| preserve_timestamps=false | |
| case "$1" in | |
| -p | --preserve-timestamps) | |
| preserve_timestamps=true | |
| shift | |
| ;; | |
| *) | |
| ;; | |
| esac | |
| if [[ "$#" -eq 0 ]]; then | |
| echo "Error: no files or directories provided" | |
| exit 1 | |
| fi | |
| # Validate that all provided files and directories exist | |
| for arg in "$@"; do | |
| if ! [[ -e "${arg}" ]]; then | |
| echo "Error: '${arg}' does not exist" | |
| exit 1 | |
| fi | |
| done | |
| timestamp_files=() | |
| timestamp_references=() | |
| timestamp_dir="" | |
| restore_timestamps() { | |
| local index | |
| local restore_failed=0 | |
| for ((index = 0; index < ${#timestamp_files[@]}; index++)); do | |
| if ! [[ -e "${timestamp_files[index]}" ]] || | |
| ! touch -r "${timestamp_references[index]}" "${timestamp_files[index]}"; then | |
| echo "Error: failed to restore timestamp for '${timestamp_files[index]}'" | |
| restore_failed=1 | |
| fi | |
| done | |
| timestamp_files=() | |
| timestamp_references=() | |
| if [[ -n "${timestamp_dir}" ]]; then | |
| if rm -rf "${timestamp_dir}"; then | |
| timestamp_dir="" | |
| else | |
| echo "Error: failed to remove temporary directory '${timestamp_dir}'" | |
| restore_failed=1 | |
| fi | |
| fi | |
| return "${restore_failed}" | |
| } | |
| save_timestamp() { | |
| local file="$1" | |
| local index="${#timestamp_files[@]}" | |
| local reference="${timestamp_dir}/${index}" | |
| : >"${reference}" | |
| if ! touch -r "${file}" "${reference}"; then | |
| echo "Error: failed to save timestamp for '${file}'" | |
| exit 1 | |
| fi | |
| timestamp_files[index]="${file}" | |
| timestamp_references[index]="${reference}" | |
| } | |
| if [[ "${preserve_timestamps}" == true ]]; then | |
| trap restore_timestamps EXIT | |
| trap 'exit 129' HUP | |
| trap 'exit 130' INT | |
| trap 'exit 131' QUIT | |
| trap 'exit 143' TERM | |
| timestamp_dir="$(mktemp -d "${TMPDIR:-/tmp}/imageoptim.XXXXXX")" || exit 1 | |
| for arg in "$@"; do | |
| if [[ -f "${arg}" ]]; then | |
| save_timestamp "${arg}" | |
| elif [[ -d "${arg}" ]]; then | |
| if ! find "${arg}" -path "${timestamp_dir}" -prune -o -type f -print0 >"${timestamp_dir}/files"; then | |
| echo "Error: failed to enumerate files in '${arg}'" | |
| exit 1 | |
| fi | |
| while IFS= read -r -d '' file; do | |
| save_timestamp "${file}" | |
| done <"${timestamp_dir}/files" | |
| fi | |
| done | |
| fi | |
| # Run ImageOptim with error handling | |
| imageoptim_exit=0 | |
| /Applications/ImageOptim.app/Contents/MacOS/ImageOptim "$@" || imageoptim_exit=$? | |
| restore_exit=0 | |
| if [[ "${preserve_timestamps}" == true ]]; then | |
| restore_timestamps || restore_exit=$? | |
| if [[ -z "${timestamp_dir}" ]]; then | |
| trap - EXIT HUP INT QUIT TERM | |
| fi | |
| fi | |
| if ((imageoptim_exit != 0)); then | |
| echo "ImageOptim failed. Check that your files are valid images." | |
| exit 1 | |
| fi | |
| exit "${restore_exit}" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment