Python實(shí)現(xiàn)批量壓縮圖片的實(shí)用腳本分享
引言:為什么需要批量壓縮圖片?
手機(jī)拍攝的4K照片動(dòng)輒10MB,單反相機(jī)拍攝的RAW格式圖片更是高達(dá)50MB以上。當(dāng)需要分享旅行照片、上傳電商產(chǎn)品圖或管理設(shè)計(jì)素材庫時(shí),龐大的圖片體積會(huì)帶來諸多困擾:云存儲(chǔ)空間快速耗盡、網(wǎng)頁加載速度變慢、郵件發(fā)送附件受限……批量壓縮圖片成為解決這些問題的關(guān)鍵手段。
通過Python腳本實(shí)現(xiàn)自動(dòng)化壓縮,不僅能精準(zhǔn)控制壓縮參數(shù),還能批量處理成百上千張圖片。相比在線工具,本地腳本無需上傳隱私圖片,處理速度更快;相比專業(yè)軟件,Python方案無需付費(fèi)且可高度定制。本文將通過實(shí)際案例,展示如何用50行代碼構(gòu)建高效圖片壓縮工具。
一、核心原理:如何實(shí)現(xiàn)圖片壓縮?
圖片壓縮主要通過兩種技術(shù)路徑實(shí)現(xiàn),Python的Pillow庫完美支持這兩種方式:
1. 尺寸壓縮:降低分辨率
原始圖片尺寸為4000×3000像素,若目標(biāo)設(shè)備僅需1920×1080顯示,直接縮小尺寸可減少75%像素量。Pillow的thumbnail()方法能自動(dòng)保持寬高比進(jìn)行縮放:
from PIL import Image
img = Image.open("photo.jpg")
img.thumbnail((1920, 1080)) # 保持比例縮放2. 質(zhì)量壓縮:優(yōu)化編碼
JPEG格式通過調(diào)整質(zhì)量參數(shù)(1-100)控制壓縮強(qiáng)度。質(zhì)量值越低,文件越小但可能產(chǎn)生噪點(diǎn)。實(shí)測(cè)顯示,質(zhì)量85時(shí)人眼難以察覺差異,但文件體積可減少60%:
img.save("compressed.jpg", quality=85, optimize=True)3. 智能組合策略
最佳實(shí)踐是同時(shí)應(yīng)用尺寸和質(zhì)量壓縮。例如將4000×3000圖片縮小至1920×1440后,再設(shè)置質(zhì)量85,實(shí)測(cè)5.2MB原圖可壓縮至320KB,體積減少94%而肉眼幾乎無差別。
二、基礎(chǔ)腳本:50行代碼實(shí)現(xiàn)批量壓縮
以下腳本支持遞歸處理子目錄,自動(dòng)創(chuàng)建輸出文件夾,并顯示壓縮進(jìn)度:
import os
from PIL import Image
from pathlib import Path
def compress_image(input_path, output_path, max_size=1920, quality=85):
"""壓縮單張圖片"""
try:
with Image.open(input_path) as img:
# 轉(zhuǎn)換模式處理透明通道
if img.mode in ("RGBA", "P"):
img = img.convert("RGB")
# 按比例縮放
img.thumbnail((max_size, max_size), Image.LANCZOS)
# 保存為JPEG格式
output_path = output_path.with_suffix('.jpg')
img.save(output_path, "JPEG", optimize=True, quality=quality)
# 計(jì)算壓縮率
orig_size = os.path.getsize(input_path)
new_size = os.path.getsize(output_path)
ratio = (1 - new_size / orig_size) * 100
print(f"? {Path(input_path).name}: {orig_size//1024}KB → {new_size//1024}KB (節(jié)省{ratio:.1f}%)")
except Exception as e:
print(f"? 壓縮失敗 {input_path}: {e}")
def batch_compress(input_folder, output_folder, max_size=1920, quality=85):
"""批量處理文件夾"""
input_path = Path(input_folder)
output_path = Path(output_folder)
output_path.mkdir(parents=True, exist_ok=True)
# 支持的圖片格式
supported_ext = ('.jpg', '.jpeg', '.png', '.bmp', '.tiff')
# 遍歷所有圖片文件
image_files = [
f for f in input_path.rglob('*')
if f.suffix.lower() in supported_ext and f.is_file()
]
if not image_files:
print("?? 指定文件夾中沒有可處理的圖片")
return
print(f"?? 找到 {len(image_files)} 張圖片,開始?jí)嚎s...")
for img_file in image_files:
rel_path = img_file.relative_to(input_path)
out_file = output_path / rel_path.with_stem(f"{rel_path.stem}_compressed")
compress_image(img_file, out_file, max_size, quality)
print(f"\n?? 全部完成!壓縮后圖片保存在: {output_folder}")
if __name__ == "__main__":
batch_compress("./photos", "./compressed", max_size=1200, quality=75)腳本特性說明:
- 智能路徑處理:使用
Path.rglob()遞歸查找所有子目錄中的圖片 - 透明通道處理:自動(dòng)將PNG的RGBA模式轉(zhuǎn)換為RGB,避免JPEG保存錯(cuò)誤
- 進(jìn)度可視化:實(shí)時(shí)顯示每張圖片的壓縮前后大小及節(jié)省比例
- 安全設(shè)計(jì):輸出路徑自動(dòng)創(chuàng)建,避免因目錄不存在導(dǎo)致的錯(cuò)誤
三、進(jìn)階優(yōu)化:滿足不同場(chǎng)景需求
1. 動(dòng)態(tài)質(zhì)量調(diào)整(SSIM算法)
對(duì)于需要極致壓縮的場(chǎng)景,可通過結(jié)構(gòu)相似性(SSIM)評(píng)估圖片質(zhì)量損失,動(dòng)態(tài)調(diào)整壓縮參數(shù):
from math import log
from SSIM_PIL import compare_ssim # 需安裝pyssim庫
def get_ssim_at_quality(photo, quality):
"""計(jì)算指定質(zhì)量下的SSIM值"""
temp_path = "temp.jpg"
photo.save(temp_path, format="JPEG", quality=quality, progressive=True)
ssim_score = compare_ssim(photo, Image.open(temp_path))
os.remove(temp_path)
return ssim_score
def find_optimal_quality(original_photo, target_ssim=0.95):
"""二分法尋找最優(yōu)質(zhì)量參數(shù)"""
low, high = 70, 95
while high - low > 2:
mid = (high + low) // 2
if get_ssim_at_quality(original_photo, mid) < target_ssim:
low = mid
else:
high = mid
return high
# 使用示例
img = Image.open("photo.jpg")
optimal_quality = find_optimal_quality(img)
img.save("optimized.jpg", quality=optimal_quality)2. 格式轉(zhuǎn)換優(yōu)化
對(duì)于截圖、圖標(biāo)等簡(jiǎn)單圖形,轉(zhuǎn)換為PNG格式并啟用調(diào)色板優(yōu)化可獲得更好效果:
def compress_png(input_path, output_path, palette_size=256):
"""PNG無損壓縮"""
img = Image.open(input_path)
if img.mode == "RGB":
# 生成最優(yōu)調(diào)色板
palleted_img = img.convert(
'P',
palette=Image.ADAPTIVE,
colors=palette_size
)
palleted_img.save(
output_path,
optimize=True,
compress_level=9 # 最大壓縮級(jí)別
)3. 多線程加速處理
處理大量圖片時(shí),使用多線程可顯著提升速度:
from concurrent.futures import ThreadPoolExecutor
def parallel_compress(input_folder, output_folder, max_workers=4):
"""多線程壓縮"""
image_files = [f for f in Path(input_folder).rglob('*')
if f.suffix.lower() in ('.jpg', '.png') and f.is_file()]
with ThreadPoolExecutor(max_workers=max_workers) as executor:
for img_file in image_files:
rel_path = img_file.relative_to(input_folder)
out_file = Path(output_folder) / rel_path.with_stem(f"{rel_path.stem}_compressed")
executor.submit(
compress_image,
img_file,
out_file,
max_size=1200,
quality=75
)四、實(shí)戰(zhàn)案例:電商圖片處理流程
某電商團(tuán)隊(duì)需要處理5000張產(chǎn)品圖,要求:
- 統(tǒng)一尺寸為800×800像素
- JPEG質(zhì)量設(shè)置為80
- 保留原始文件名并添加"_web"后綴
- 生成處理報(bào)告
解決方案:
import pandas as pd
from datetime import datetime
def ecommerce_compress(input_folder, output_folder):
"""電商圖片專用壓縮流程"""
results = []
start_time = datetime.now()
for img_file in Path(input_folder).rglob('*.jpg'):
try:
# 創(chuàng)建輸出路徑
rel_path = img_file.relative_to(input_folder)
out_file = Path(output_folder) / rel_path.with_stem(f"{rel_path.stem}_web")
out_file.parent.mkdir(parents=True, exist_ok=True)
# 壓縮處理
with Image.open(img_file) as img:
# 強(qiáng)制正方形裁剪(需先安裝opencv-python)
# import cv2
# img = cv2.resize(np.array(img), (800,800))
# img = Image.fromarray(img)
# 簡(jiǎn)單縮放方案
img.thumbnail((800, 800), Image.LANCZOS)
img.save(out_file, "JPEG", quality=80, optimize=True)
# 記錄結(jié)果
results.append({
"文件名": img_file.name,
"原始大小(KB)": os.path.getsize(img_file)//1024,
"壓縮后(KB)": os.path.getsize(out_file)//1024,
"狀態(tài)": "成功"
})
except Exception as e:
results.append({
"文件名": img_file.name,
"原始大小(KB)": "-",
"壓縮后(KB)": "-",
"狀態(tài)": f"失敗: {str(e)}"
})
# 生成報(bào)告
df = pd.DataFrame(results)
report_path = Path(output_folder) / f"壓縮報(bào)告_{datetime.now().strftime('%Y%m%d')}.csv"
df.to_csv(report_path, index=False)
print(f"\n處理完成!耗時(shí): {(datetime.now()-start_time).seconds}秒")
print(f"詳細(xì)報(bào)告已生成: {report_path}")
# 使用示例
ecommerce_compress("./raw_images", "./web_images")五、常見問題解決方案
1. 處理透明背景圖片
錯(cuò)誤做法:直接保存為JPEG會(huì)丟失透明通道
正確方案:
def handle_transparency(input_path, output_path):
img = Image.open(input_path)
if img.mode == "RGBA":
# 創(chuàng)建白色背景
background = Image.new("RGB", img.size, (255, 255, 255))
background.paste(img, mask=img.split()[-1])
background.save(output_path, "JPEG", quality=85)
else:
img.save(output_path, "JPEG", quality=85)2. 保留EXIF信息
使用piexif庫可保留照片的拍攝參數(shù):
import piexif
def save_with_exif(img, output_path, quality=85):
"""保存圖片并保留EXIF信息"""
exif_dict = piexif.load(img.info['exif']) if 'exif' in img.info else {}
img.save(
output_path,
"JPEG",
quality=quality,
exif=piexif.dump(exif_dict)
)3. 處理超大圖片
對(duì)于超過100MB的TIFF格式圖片,需先分塊處理:
from PIL import ImageSequence
def process_large_tiff(input_path, output_path):
"""分塊處理超大TIFF文件"""
with Image.open(input_path) as img:
for i, page in enumerate(ImageSequence.Iterator(img)):
page.thumbnail((4000, 4000)) # 先縮小尺寸
page.save(
f"{output_path}_page{i}.jpg",
"JPEG",
quality=80,
optimize=True
)六、性能對(duì)比:不同壓縮方案效率
| 方案 | 處理速度 | 壓縮率 | 質(zhì)量損失 | 適用場(chǎng)景 |
|---|---|---|---|---|
| 單純尺寸壓縮 | ★★★★★ | 中 | 無 | 網(wǎng)頁顯示 |
| 質(zhì)量85壓縮 | ★★★★ | 高 | 輕微 | 電商產(chǎn)品圖 |
| SSIM動(dòng)態(tài)質(zhì)量調(diào)整 | ★★★ | 極高 | 極小 | 高端攝影作品 |
| PNG調(diào)色板優(yōu)化 | ★★ | 中 | 無 | 簡(jiǎn)單圖形/圖標(biāo) |
| 多線程處理 | ★★★★★ | 高 | 同單線程 | 批量處理 |
實(shí)測(cè)數(shù)據(jù)顯示:5000張圖片處理時(shí),單線程需2小時(shí),8線程方案僅需25分鐘。
七、總結(jié):構(gòu)建個(gè)性化圖片處理流水線
通過組合本文介紹的技術(shù)模塊,可構(gòu)建滿足不同需求的圖片處理系統(tǒng):
- 基礎(chǔ)版:尺寸+質(zhì)量壓縮(適合大多數(shù)場(chǎng)景)
- 電商版:正方形裁剪+水印添加+EXIF保留
- 攝影版:SSIM動(dòng)態(tài)質(zhì)量+漸進(jìn)式JPEG
- 極速版:多線程處理+緩存機(jī)制
建議從基礎(chǔ)腳本開始,根據(jù)實(shí)際需求逐步添加功能模塊。對(duì)于非技術(shù)用戶,可使用PyInstaller將腳本打包為EXE文件,無需安裝Python環(huán)境即可運(yùn)行。
圖片壓縮的本質(zhì)是在文件體積與視覺質(zhì)量間尋找平衡點(diǎn)。掌握這些技術(shù)后,您不僅能節(jié)省存儲(chǔ)空間,更能為網(wǎng)站加速、移動(dòng)應(yīng)用優(yōu)化等場(chǎng)景提供關(guān)鍵支持。
以上就是Python批量壓縮圖片的實(shí)用腳本分享的詳細(xì)內(nèi)容,更多關(guān)于Python批量壓縮圖片的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Nginx配置移動(dòng)端和PC端自動(dòng)跳轉(zhuǎn)方式
文章介紹了如何通過Nginx配置PC端和移動(dòng)端自動(dòng)跳轉(zhuǎn),PC端和移動(dòng)端各有獨(dú)立的域名,PC端訪問任何域名時(shí)會(huì)跳轉(zhuǎn)到www.yxf.com,移動(dòng)端訪問任何域名時(shí)會(huì)跳轉(zhuǎn)到m.yxf.com,配置時(shí)需要修改Nginx的conf文件,使用302或301重定向2025-11-11
Nginx反向代理多個(gè)服務(wù)器的實(shí)現(xiàn)方法
這篇文章主要介紹了Nginx反向代理多個(gè)服務(wù)器的實(shí)現(xiàn)方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-02-02
Windows Server 2016 MySQL數(shù)據(jù)庫安裝配置詳細(xì)安裝教程
這篇文章主要介紹了Windows Server 2016 MySQL數(shù)據(jù)庫安裝配置詳細(xì)安裝教程,需要的朋友可以參考下2017-08-08
nginx和lvs各自的優(yōu)劣以及適合的使用環(huán)境
這篇文章主要介紹了nginx和lvs各自的優(yōu)劣以及適合的使用環(huán)境,幫助大家選擇符合需求的服務(wù)器,感興趣的朋友可以了解下2020-10-10
Nginx路由匹配規(guī)則及優(yōu)先級(jí)詳解
Nginx作為一個(gè)高性能的Web服務(wù)器和反向代理服務(wù)器,廣泛用于負(fù)載均衡、請(qǐng)求轉(zhuǎn)發(fā)等場(chǎng)景,在配置Nginx時(shí),路由匹配規(guī)則是非常重要的概念,本文將詳細(xì)介紹Nginx的路由匹配規(guī)則及其優(yōu)先級(jí),需要的朋友可以參考下2025-05-05
keepalived監(jiān)控nginx進(jìn)程的實(shí)現(xiàn)示例
本文主要介紹了keepalived監(jiān)控nginx進(jìn)程的實(shí)現(xiàn)示例,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2024-08-08
Nginx的流式響應(yīng)配置實(shí)現(xiàn)小結(jié)
nginx是一款自由的、開源的、高性能的HTTP服務(wù)器和反向代理服務(wù)器,本文主要介紹了Nginx的流式響應(yīng)配置實(shí)現(xiàn)小結(jié),具有一定的參考價(jià)值,感興趣的可以了解一下2024-04-04

