首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 更多程式設計知識

Python PIL/Pillow 批次等比縮圖腳本:glob 遞迴、多執行緒加速、EXIF 保留與錯誤處理

     編輯:更多程式設計知識

使用 Pillow (PIL 友善分支) 實作批次等比縮圖,支援遞迴尋找、多執行緒並行、EXIF 方向修正、錯誤隔離與進度顯示。

安裝依賴


pip install Pillow

核心單張處理函數


from PIL import Image, ImageOps
import os

def resize_image(src_path, dst_path, scale=0.12, max_dim=None, quality=85):
    """
    等比縮放單張圖片
    :param scale: 縮放比例 (0-1)
    :param max_dim: 最大邊長像素 (優先於 scale)
    :param quality: JPEG 品質 (1-95)
    """
    try:
        with Image.open(src_path) as img:
            # 修正 EXIF 方向 (避免手機照片旋轉)
            img = ImageOps.exif_transpose(img)
            
            orig_w, orig_h = img.size
            
            if max_dim:
                scale = min(max_dim / orig_w, max_dim / orig_h, 1.0)
            
            if scale >= 1.0:
                new_w, new_h = orig_w, orig_h
            else:
                new_w, new_h = int(orig_w * scale), int(orig_h * scale)
            
            # 高品質重採樣
            resized = img.resize((new_w, new_h), Image.LANCZOS)
            
            # 保留 EXIF (若為 JPEG)
            exif = img.info.get('exif')
            save_kwargs = {'quality': quality, 'optimize': True}
            if exif:
                save_kwargs['exif'] = exif
            
            # 確保輸出目錄存在
            os.makedirs(os.path.dirname(dst_path), exist_ok=True)
            resized.save(dst_path, **save_kwargs)
            
        return True, f'{orig_w}x{orig_h} -> {new_w}x{new_h}'
    except Exception as e:
        return False, str(e)

批次處理主程式 (多執行緒版)


import glob
import os
from concurrent.futures import ThreadPoolExecutor, as_completed
from tqdm import tqdm  # pip install tqdm

def batch_resize(src_dir, dst_dir, pattern='**/*.jpg', scale=0.12, max_workers=4):
    # 遞迴尋找檔案
    search_path = os.path.join(src_dir, pattern)
    files = glob.glob(search_path, recursive=True)
    
    if not files:
        print('找不到符合條件的檔案')
        return
    
    print(f'找到 {len(files)} 個檔案,開始處理...')
    
    success = 0
    failed = []
    
    with ThreadPoolExecutor(max_workers=max_workers) as executor:
        # 提交所有任務
        future_to_file = {}
        for src in files:
            rel = os.path.relpath(src, src_dir)
            dst = os.path.join(dst_dir, rel)
            future = executor.submit(resize_image, src, dst, scale)
            future_to_file[future] = src
        
        # 進度條收集結果
        for future in tqdm(as_completed(future_to_file), total=len(files), desc='縮圖中'):
            src = future_to_file[future]
            ok, msg = future.result()
            if ok:
                success += 1
            else:
                failed.append((src, msg))
    
    print(f'\n完成:成功 {success},失敗 {len(failed)}')
    for src, err in failed:
        print(f'  失敗: {src} -> {err}')

if __name__ == '__main__':
    import argparse
    parser = argparse.ArgumentParser(description='批次等比縮圖')
    parser.add_argument('src', help='來源目錄')
    parser.add_argument('dst', help='輸出目錄')
    parser.add_argument('--scale', type=float, default=0.12, help='縮放比例 (預設 0.12)')
    parser.add_argument('--max-dim', type=int, help='最大邊長 (像素)')
    parser.add_argument('--workers', type=int, default=4, help='執行緒數')
    args = parser.parse_args()
    
    batch_resize(args.src, args.dst, scale=args.scale, max_workers=args.workers)

使用範例


# 基本用法
python batch_resize.py ./photos ./thumbnails

# 指定最大邊長 800px
python batch_resize.py ./photos ./thumbnails --max-dim 800

# 8 執行緒加速
python batch_resize.py ./photos ./thumbnails --workers 8

關鍵技術細節

功能實作要點
遞迴尋找glob.glob('**/*.jpg', recursive=True)
EXIF 方向修正ImageOps.exif_transpose(img) 自動旋轉
高品質重採樣Image.LANCZOS (Lanczos 濾波器)
EXIF 保留讀取 img.info['exif'] 寫入 save(exif=...)
多執行緒ThreadPoolExecutor 適合 IO 密集型 (讀寫磁碟)
進度條tqdm 視覺化進度
錯誤隔離單檔失敗不影響其他,統一收集錯誤報告

常見格式支援


# 擴充支援格式
patterns = ['**/*.jpg', '**/*.jpeg', '**/*.png', '**/*.webp', '**/*.tiff']
for pattern in patterns:
    batch_resize(src, dst, pattern=pattern, ...)

此腳本可直接用於生產環境縮圖需求,配合 cron 或 systemd timer 實現定期自動處理。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved