shell 案例
批量压缩图片大小
场景
因为之前在文章中引用了很多手机拍摄图片,没注意图片体积,自己浏览时发现加载特别慢。所以想着再优化一下,我记得最开始写过类似脚本,但是找不到了,这次刚好记录一下。在AI帮助下,脚本在多次迭代优化后,已经比较稳定实用。
主要原是通过ImageMagick、jpegoptim和optipng工具,将图片压缩至指定大小,支持JPG/PNG格式,并采用多线程并行处理提升效率。
脚本分享
以下脚本支持将JPG/PNG图片压缩至指定大小(例如 100KB 以下),并自动跳过已经达标的文件。。只需要在需要处理的目录下运行脚本即可。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103
| #!/bin/bash
# ===================== 核心配置 ===================== TARGET_SIZE_KB=100 # 目标大小:100KB TARGET_SIZE=$((TARGET_SIZE_KB * 1024)) MAX_RESOLUTION=1000 # 网页合适分辨率 JPG_QUALITY=60 # JPG压缩质量 THREADS=20 # 24核用20线程 # ====================================================
# 检查依赖工具 check_dependency() { local cmd=$1 local name=$2 if ! command -v $cmd &> /dev/null; then echo "❌ 缺少必要工具:$name,请先安装!" echo "Ubuntu/Debian: sudo apt install jpegoptim optipng imagemagick -y" echo "macOS: brew install jpegoptim optipng imagemagick" exit 1 fi }
# 检查关键依赖 check_dependency "convert" "ImageMagick" check_dependency "jpegoptim" "jpegoptim" check_dependency "optipng" "optipng"
# 获取当前目录 CURRENT_DIR=$(pwd) echo "========================================" echo "当前目录:$CURRENT_DIR" echo "目标:压缩至${TARGET_SIZE_KB}KB以下(${THREADS}线程)" echo "========================================" process_image() { local img=$1 local TARGET_SIZE=$2 local MAX_RESOLUTION=$3 local JPG_QUALITY=$4 local filename=$(basename "$img")
# 工具函数:获取文件大小KB(兼容Linux和macOS) get_file_size_kb() { if [[ $(uname) == "Darwin" ]]; then echo "scale=2; $(stat -f%z "$1")/1024" | bc else echo "scale=2; $(stat -c%s "$1")/1024" | bc fi }
# 工具函数:检查是否达标 is_size_ok() { [[ $(stat -c%s "$1") -le $2 ]] }
# 已达标则跳过 if is_size_ok "$img" "$TARGET_SIZE"; then echo "⏩ $filename - 已达标($(get_file_size_kb "$img")KB),跳过" return 0 fi
# 区分JPG/PNG处理 if [[ $img =~ \.(jpg|jpeg)$ ]]; then echo "🔍 处理JPG:$filename(原大小:$(get_file_size_kb "$img")KB)" # JPG压缩逻辑 convert "$img" -resize "${MAX_RESOLUTION}x${MAX_RESOLUTION}>" -strip "$img" jpegoptim --max=$JPG_QUALITY --strip-all --overwrite "$img" # 兜底检查 if ! is_size_ok "$img" "$TARGET_SIZE"; then jpegoptim --max=40 --strip-all --overwrite "$img" fi echo "✅ $filename - 压缩后:$(get_file_size_kb "$img")KB"
elif [[ $img =~ \.png$ ]]; then echo "🔍 处理PNG:$filename(原大小:$(get_file_size_kb "$img")KB)" # PNG压缩逻辑 convert "$img" -resize "${MAX_RESOLUTION}x${MAX_RESOLUTION}>" -strip "$img" optipng -o6 -strip all -force "$img" # 兜底检查 if ! is_size_ok "$img" "$TARGET_SIZE"; then optipng -o9 -strip all -force "$img" fi echo "✅ $filename - 压缩后:$(get_file_size_kb "$img")KB" fi }
# 导出函数(确保子shell可见) export -f process_image
# ===================== 多线程执行 ===================== echo -e "\n[开始多线程处理所有图片(${THREADS}线程)]"
find "$CURRENT_DIR" -maxdepth 1 -type f \( -iname "*.jpg" -o -iname "*.jpeg" -o -iname "*.png" \) -print0 | \ xargs -0 -I {} -P $THREADS bash -c 'process_image "$1" "$2" "$3" "$4"' _ {} $TARGET_SIZE $MAX_RESOLUTION $JPG_QUALITY
echo -e "\n========================================" echo "处理完成!" echo "========================================"
|
参数说明
脚本开头的配置项可以根据实际需求调整:
| 参数 |
说明 |
推荐值 |
| TARGET_SIZE_KB |
目标图片大小 |
100 |
| MAX_RESOLUTION |
最大分辨率限制 |
1000 |
| JPG_QUALITY |
JPG压缩质量 |
60 |
| THREADS |
并行线程数 |
CPU核心数 × 0.8 |
我电脑是24核CPU,使用20线程较为合适。
注意事项
1、脚本会直接覆盖原始图片,建议首次使用前先备份图片目录。
2、图片体积变小,图片质量就会下降,还是权衡后选择是否优化。