返回顶部
热门问答 更多热门问答

服务器执行图片批处理:image_compress.py

[复制链接]
admin 显示全部楼层 发表于 2026-1-18 17:50:10 |阅读模式 打印 上一主题 下一主题
  1. import os
  2. import sys
  3. from PIL import Image
  4. from tqdm import tqdm
  5. import traceback

  6. # 配置项(可根据需要修改)
  7. TARGET_QUALITY = 50  # 压缩质量(1-100,数值越小压缩率越高)
  8. MAX_WIDTH = 1024     # 最大宽度,超过则等比例缩放
  9. SUPPORT_FORMATS = ('.jpg', '.jpeg', '.png', '.bmp')  # 支持的图片格式

  10. def compress_image(file_path):
  11.     """
  12.     处理单张图片:缩放+压缩
  13.     :param file_path: 图片文件的绝对路径
  14.     :return: (是否成功, 原大小/KB, 新大小/KB, 错误信息)
  15.     """
  16.     try:
  17.         # 获取文件原始大小
  18.         original_size = os.path.getsize(file_path) / 1024  # 转KB

  19.         # 打开图片(处理PNG透明通道问题)
  20.         with Image.open(file_path) as img:
  21.             # 1. 处理尺寸:宽度超过MAX_WIDTH则等比例缩放
  22.             width, height = img.size
  23.             if width > MAX_WIDTH:
  24.                 ratio = MAX_WIDTH / width
  25.                 new_height = int(height * ratio)
  26.                 # 缩放图片(保留原图质量的缩放算法)
  27.                 img = img.resize((MAX_WIDTH, new_height), Image.Resampling.LANCZOS)

  28.             # 2. 处理压缩并保存(覆盖原文件,保持原格式)
  29.             # 区分JPEG和PNG/BMP的保存参数
  30.             file_ext = os.path.splitext(file_path)[1].lower()
  31.             save_kwargs = {}
  32.             if file_ext in ('.jpg', '.jpeg'):
  33.                 # JPEG压缩:设置质量,关闭渐进式(加快加载)
  34.                 save_kwargs['quality'] = TARGET_QUALITY
  35.                 save_kwargs['optimize'] = True
  36.                 save_kwargs['progressive'] = False
  37.             elif file_ext == '.png':
  38.                 # PNG压缩:优化压缩
  39.                 save_kwargs['optimize'] = True
  40.             elif file_ext == '.bmp':
  41.                 # BMP无质量参数,仅缩放
  42.                 pass

  43.             # 保存图片(覆盖原文件)
  44.             img.save(file_path, **save_kwargs)

  45.         # 获取处理后文件大小
  46.         new_size = os.path.getsize(file_path) / 1024
  47.         return (True, original_size, new_size, "")
  48.    
  49.     except Exception as e:
  50.         # 捕获异常并返回错误信息
  51.         error_info = traceback.format_exc()[:200]  # 截取前200字符,避免信息过长
  52.         return (False, 0, 0, error_info)

  53. def batch_compress(root_dir):
  54.     """
  55.     批量处理指定目录下的所有图片(递归遍历子目录)
  56.     :param root_dir: 目标根目录
  57.     """
  58.     # 第一步:收集所有符合条件的图片文件路径
  59.     image_files = []
  60.     for root, dirs, files in os.walk(root_dir):
  61.         for file in files:
  62.             file_ext = os.path.splitext(file)[1].lower()
  63.             if file_ext in SUPPORT_FORMATS:
  64.                 file_path = os.path.join(root, file)
  65.                 image_files.append(file_path)
  66.    
  67.     if not image_files:
  68.         print(f"⚠️  在目录 {root_dir} 下未找到任何支持的图片文件({SUPPORT_FORMATS})")
  69.         return

  70.     # 第二步:批量处理图片,显示进度条
  71.     success_count = 0
  72.     fail_count = 0
  73.     total_original_size = 0  # 总原始大小(KB)
  74.     total_new_size = 0       # 总处理后大小(KB)

  75.     print(f"\n📌 共发现 {len(image_files)} 张待处理图片,开始批量压缩...\n")
  76.     # 进度条配置:显示当前文件、进度、速度
  77.     pbar = tqdm(image_files, desc="处理进度", unit="张", ncols=100)
  78.     for file_path in pbar:
  79.         # 更新进度条的当前文件提示
  80.         pbar.set_postfix(file=os.path.basename(file_path))
  81.         
  82.         # 处理单张图片
  83.         success, ori_size, new_size, error = compress_image(file_path)
  84.         
  85.         # 统计数据
  86.         if success:
  87.             success_count += 1
  88.             total_original_size += ori_size
  89.             total_new_size += new_size
  90.         else:
  91.             fail_count += 1
  92.             # 失败时在进度条后标注错误
  93.             tqdm.write(f"❌ 处理失败 {file_path}:{error}")
  94.    
  95.     # 第三步:输出统计结果
  96.     pbar.close()
  97.     print(f"\n✅ 处理完成!")
  98.     print(f"   成功:{success_count} 张 | 失败:{fail_count} 张")
  99.     print(f"   原始总大小:{total_original_size:.2f} KB | 压缩后总大小:{total_new_size:.2f} KB")
  100.     if total_original_size > 0:
  101.         compression_rate = (1 - total_new_size / total_original_size) * 100
  102.         print(f"   整体压缩率:{compression_rate:.2f}%")

  103. if __name__ == "__main__":
  104.     # 检查命令行参数:需要传入目标目录路径
  105.     if len(sys.argv) != 2:
  106.         print("🔧 使用方法:python image_compress.py 目标目录路径")
  107.         print("   示例:python image_compress.py /www/wwwroot/your_site/images")
  108.         sys.exit(1)
  109.    
  110.     target_dir = sys.argv[1]
  111.     # 验证目录是否存在
  112.     if not os.path.isdir(target_dir):
  113.         print(f"❌ 错误:目录 {target_dir} 不存在!")
  114.         sys.exit(1)
  115.    
  116.     # 开始批量处理
  117.     batch_compress(target_dir)
复制代码



使用说明:

打开宝塔的「终端」(或通过 SSH 连接服务器),执行以下命令安装依赖库:
pip install pillow tqdm

执行脚本:
执行以下命令(替换为你的图片目录路径):
# 示例:处理 /www/wwwroot/你的网站域名/images 目录下的所有图片
python /www/image_compress.py /www/wwwroot/your_site/images





本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

星点互联 成立于2014年8月,是目前国内优秀的开源技术社区,拥有超过300万会员,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作