#!/bin/bash
# ── 收集傳入的圖片路徑 ──────────────────────────────────────
FILES=("$@")
if [ ${#FILES[@]} -eq 0 ]; then
# 直接雙擊啟動時,開啟選檔視窗
SELECTED=$(osascript <<'EOF'
set chosen to choose file with prompt "選擇要轉換的圖片(可多選):" of type {"public.png", "public.jpeg"} with multiple selections allowed
set filePaths to ""
repeat with f in chosen
set filePaths to filePaths & POSIX path of f & linefeed
end repeat
return filePaths
EOF
)
if [ $? -ne 0 ] || [ -z "$SELECTED" ]; then
exit 0
fi
# 將選取的路徑轉成陣列
while IFS= read -r line; do
[ -n "$line" ] && FILES+=("$line")
done <<< "$SELECTED"
fi
# ── 用 AppleScript 顯示設定對話框 ──────────────────────────
SETTINGS=$(osascript <<'EOF'
set dialogResult to {}
-- 1. 寬度輸入
set widthInput to text returned of (display dialog "輸入輸出寬度(像素):
留空 = 不限制寬度" default answer "1920" with title "批次圖片轉換工具" buttons {"取消", "下一步"} default button "下一步")
if widthInput is "" then set widthInput to "0"
-- 2. 高度輸入
set heightInput to text returned of (display dialog "輸入輸出高度(像素):
留空 = 不限制高度" default answer "" with title "批次圖片轉換工具" buttons {"取消", "下一步"} default button "下一步")
if heightInput is "" then set heightInput to "0"
-- 3. 等比例縮放
set scaleChoice to button returned of (display dialog "縮放方式:
- 等比例:依寬度等比換算高度(推薦)
- 強制尺寸:強制裁切為指定長寬" with title "批次圖片轉換工具" buttons {"強制尺寸", "等比例"} default button "等比例")
-- 4. 壓縮品質
set qualityInput to text returned of (display dialog "輸出品質(1–100):
100 = 最高品質,70 = 一般,50 = 較小檔案" default answer "85" with title "批次圖片轉換工具" buttons {"取消", "下一步"} default button "下一步")
-- 5. 輸出格式
set formatChoice to button returned of (display dialog "輸出格式:" with title "批次圖片轉換工具" buttons {"PNG", "JPG"} default button "JPG")
-- 6. 輸出目錄
set outputFolder to POSIX path of (choose folder with prompt "選擇輸出目錄:")
-- 回傳所有設定(用 | 分隔)
return widthInput & "|" & heightInput & "|" & scaleChoice & "|" & qualityInput & "|" & formatChoice & "|" & outputFolder
EOF
)
# 檢查使用者是否取消
if [ $? -ne 0 ]; then
exit 0
fi
# ── 解析設定值 ──────────────────────────────────────────────
IFS='|' read -r WIDTH HEIGHT SCALE_MODE QUALITY FORMAT OUTPUT_DIR <<< "$SETTINGS"
# 清理路徑結尾斜線
OUTPUT_DIR="${OUTPUT_DIR%/}"
# 確保輸出目錄存在
mkdir -p "$OUTPUT_DIR"
# 格式轉小寫
FORMAT_LOWER=$(echo "$FORMAT" | tr '[:upper:]' '[:lower:]')
if [ "$FORMAT_LOWER" = "jpg" ]; then
SIPS_FORMAT="jpeg"
EXT="jpg"
else
SIPS_FORMAT="png"
EXT="png"
fi
# ── 批次處理每張圖片 ────────────────────────────────────────
SUCCESS=0
FAIL=0
ERRORS=""
for FILE in "${FILES[@]}"; do
# 只處理 PNG / JPG
LOWER=$(echo "$FILE" | tr '[:upper:]' '[:lower:]')
if [[ "$LOWER" != *.png && "$LOWER" != *.jpg && "$LOWER" != *.jpeg ]]; then
FAIL=$((FAIL + 1))
ERRORS="$ERRORS\n• $(basename "$FILE")(不支援的格式)"
continue
fi
# 產生輸出檔名(去除原副檔名,加上新副檔名)
BASENAME=$(basename "$FILE")
NOEXT="${BASENAME%.*}"
OUTFILE="$OUTPUT_DIR/${NOEXT}.${EXT}"
# 避免覆蓋同名檔案
COUNTER=1
while [ -f "$OUTFILE" ]; do
OUTFILE="$OUTPUT_DIR/${NOEXT}_${COUNTER}.${EXT}"
COUNTER=$((COUNTER + 1))
done
# 先複製到輸出路徑,再用 sips 處理
cp "$FILE" "$OUTFILE"
# 建立 sips 指令
SIPS_CMD="sips"
# 格式轉換
SIPS_CMD="$SIPS_CMD -s format $SIPS_FORMAT"
# 壓縮品質(僅 JPEG 有效,sips 接受整數 0–100)
if [ "$SIPS_FORMAT" = "jpeg" ] && [ -n "$QUALITY" ]; then
SIPS_CMD="$SIPS_CMD -s formatOptions $QUALITY"
fi
# 縮放處理
if [ "$SCALE_MODE" = "等比例" ]; then
if [ "$WIDTH" != "0" ] && [ -n "$WIDTH" ]; then
SIPS_CMD="$SIPS_CMD --resampleWidth $WIDTH"
elif [ "$HEIGHT" != "0" ] && [ -n "$HEIGHT" ]; then
SIPS_CMD="$SIPS_CMD --resampleHeight $HEIGHT"
fi
else
# 強制尺寸(需要寬高都有值才執行)
if [ "$WIDTH" != "0" ] && [ "$HEIGHT" != "0" ] && [ -n "$WIDTH" ] && [ -n "$HEIGHT" ]; then
SIPS_CMD="$SIPS_CMD --resampleHeightWidth $HEIGHT $WIDTH"
elif [ "$WIDTH" != "0" ] && [ -n "$WIDTH" ]; then
SIPS_CMD="$SIPS_CMD --resampleWidth $WIDTH"
elif [ "$HEIGHT" != "0" ] && [ -n "$HEIGHT" ]; then
SIPS_CMD="$SIPS_CMD --resampleHeight $HEIGHT"
fi
fi
SIPS_CMD="$SIPS_CMD \"$OUTFILE\""
# 執行轉換
if eval $SIPS_CMD 2>/dev/null; then
SUCCESS=$((SUCCESS + 1))
else
FAIL=$((FAIL + 1))
ERRORS="$ERRORS\n• $(basename "$FILE")(轉換失敗)"
rm -f "$OUTFILE"
fi
done
# ── 顯示完成通知 ─────────────────────────────────────────────
SUMMARY="✅ 成功轉換:$SUCCESS 張\n❌ 失敗:$FAIL 張"
if [ -n "$ERRORS" ]; then
SUMMARY="$SUMMARY\n\n失敗檔案:$ERRORS"
fi
BUTTON=$(osascript -e "display dialog \"$SUMMARY\" with title \"批次轉換完成\" buttons {\"開啟輸出目錄\", \"關閉\"} default button \"關閉\"" 2>/dev/null)
if [[ "$BUTTON" == *"開啟輸出目錄"* ]]; then
open "$OUTPUT_DIR"
fi