Last active
August 19, 2025 05:24
-
-
Save kkotaro0111/3c85f0467ba389f07b1dbb45e90eedce to your computer and use it in GitHub Desktop.
mozjpegで指定したフォルダ内の画像を再圧縮する
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 | |
| # エラーが発生した場合、およびパイプラインでエラーが発生した場合にスクリプトを終了する | |
| set -e | |
| set -o pipefail | |
| # --- ヘルプメッセージ --- | |
| usage() { | |
| cat <<EOF | |
| Usage: $(basename "$0") [OPTIONS] <directory> <quality> | |
| Re-compresses all JPEG files in a directory using mozjpeg's cjpeg. | |
| Original files are moved to a subdirectory named '_original'. | |
| Arguments: | |
| <directory> The target directory containing JPEG files. | |
| <quality> The compression quality (0-100). | |
| Options: | |
| -n, --dry-run Show what would be done, without actually modifying any files. | |
| -h, --help Display this help message and exit. | |
| EOF | |
| exit 1 | |
| } | |
| # --- 初期値 --- | |
| DRY_RUN=0 | |
| # --- オプション解析 --- | |
| # getoptsではなく、より柔軟なループを使用 | |
| while [[ $# -gt 0 ]]; do | |
| case "$1" in | |
| -n|--dry-run) | |
| DRY_RUN=1 | |
| shift # 引数をシフト | |
| ;; | |
| -h|--help) | |
| usage | |
| ;; | |
| --) | |
| shift # -- の後を引数として扱う | |
| break | |
| ;; | |
| -*) | |
| echo "Unknown option: $1" | |
| usage | |
| ;; | |
| *) | |
| break # オプション以外の引数が見つかったらループを抜ける | |
| ;; | |
| esac | |
| done | |
| # --- 引数のチェック --- | |
| if [ "$#" -ne 2 ]; then | |
| echo "Error: Missing directory or quality argument." | |
| usage | |
| fi | |
| TARGET_DIR=$1 | |
| QUALITY=$2 | |
| COMPRESSED_DIR="$(dirname "$TARGET_DIR")/$(basename "$TARGET_DIR")_compressed" | |
| # --- 依存関係のチェック --- | |
| for cmd in cjpeg find mv mkdir basename; do | |
| if ! command -v "$cmd" &> /dev/null; then | |
| echo "Error: Required command '$cmd' is not available in your PATH." | |
| exit 1 | |
| fi | |
| done | |
| # --- 入力値の検証 --- | |
| if [ ! -d "$TARGET_DIR" ]; then | |
| echo "Error: Directory '$TARGET_DIR' not found." | |
| exit 1 | |
| fi | |
| if ! [[ "$QUALITY" =~ ^[0-9]+$ ]] || [ "$QUALITY" -lt 0 ] || [ "$QUALITY" -gt 100 ]; then | |
| echo "Error: Quality must be a number between 0 and 100." | |
| exit 1 | |
| fi | |
| # --- ドライランの表示 --- | |
| if [ "$DRY_RUN" -eq 1 ]; then | |
| echo "*** This is a DRY RUN. No files will be changed. ***" | |
| echo "----------------------------------------------------" | |
| fi | |
| echo "Target directory: $TARGET_DIR" | |
| echo "Quality: $QUALITY" | |
| echo "Comporession directory: $COMPRESSED_DIR" | |
| echo "" | |
| # --- 処理の実行 --- | |
| if [ "$DRY_RUN" -eq 0 ]; then | |
| mkdir -p "$COMPRESSED_DIR" | |
| fi | |
| processed_files=0 | |
| # findで見つかったファイルを配列に格納してからループ処理 | |
| mapfile -t -d '' files < <(find "$TARGET_DIR" -type f \( -iname "*.jpg" -o -iname "*.jpeg" \) -print0) | |
| for file in "${files[@]}"; do | |
| filename=$(basename "$file") | |
| # 相対パスを取得してサブディレクトリ構造を保持 | |
| relative_path="${file#$TARGET_DIR/}" | |
| convert_file="${COMPRESSED_DIR}/${relative_path}" | |
| working_dir=$(dirname "$convert_file") | |
| if [ "$DRY_RUN" -eq 1 ]; then | |
| echo "[DRY RUN] Would re-compress to '$convert_file' with quality $QUALITY" | |
| else | |
| echo "Processing: $relative_path" | |
| # 1. 作業ディレクトリを作成 | |
| if ! mkdir -p "$working_dir"; then | |
| echo "Error: Failed to create working directory '$working_dir'" | |
| continue | |
| fi | |
| # 2. 再圧縮 | |
| if cjpeg -quality "$QUALITY" "$file" > "$convert_file" 2>/dev/null; then | |
| echo "✓ Successfully processed: $relative_path" | |
| else | |
| echo "Error: Failed to compress '$relative_path'." | |
| continue | |
| fi | |
| fi | |
| processed_files=$((processed_files + 1)) | |
| done | |
| echo "----------------------------------------------------" | |
| if [ "$processed_files" -eq 0 ]; then | |
| echo "No JPEG files found to process." | |
| else | |
| if [ "$DRY_RUN" -eq 1 ]; then | |
| echo "Dry run complete. Found $processed_files JPEG file(s)." | |
| else | |
| echo "Successfully re-compressed $processed_files JPEG file(s)." | |
| fi | |
| fi |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment