封面圖片由 ChatGPT 生成。
前言
在平時建立網站頁面時,我們會發現有時候有些頁面需要讀取一段時間才能出現,而有些頁面卻沒有。經過比較不同網頁後得出一個結論,網頁內的圖片如果大小過大,會造成網頁讀取速度較慢,因此萌生出要找到一款能夠壓縮目前網站目錄下所有圖片工具。
但找來找去,網路上都沒有找到合適的應用程式,最後決定自己製作一款能夠壓縮所有圖片的程式。
需求
在開始製作前,我確認自己所需要的需求如下:
- 能夠調節壓縮圖片的程度。
- 能夠選擇是否要保留原始圖片在原目錄,方便以後重新調用。
- 能夠略過一些不必要的圖片,或者是已經壓縮過的圖片。
- 能夠產生壓縮報表,確定此次節省的空間。
而以下工具便是基於上述中目前所遇到的需求建立的。本文並不琢磨於如何進行此工具的開發,僅介紹此工具的用法。如國對此工具有任何建議、需要修正的部分,歡迎您留言指教。
Image Compression Tool
是一個基於 Python 開發的命令行圖片壓縮工具,支援壓縮指定資料夾內的所有圖片,並自動備份原圖、略過重複壓縮,並可產生詳細的壓縮報告(CSV 檔案)。
本專案使用 Python 開發,主要透過 PIL
模組進行圖片壓縮,支援的圖片格式包括:.jpg
、.jpeg
、.png
、.webp
、.bmp
、.tiff
、.gif
、.avif
、.heic
。
其中,.png
格式的壓縮效率較差。在某些情況下,若圖片已無可壓縮空間,或設定的壓縮品質過低,可能會出現壓縮後的檔案反而比原始檔案還大的情形。
- 語言:繁體中文 / 英文
- 版本:v.1.0 / v.1140621
- 最後更新日期:2025年6月21日
開發環境
操作系統環境如下:
項目 | 說明 |
---|
作業系統 | Windows 11 24H2 |
Python | 使用 3.12.9 製作 |
使用的模組如下:
模組 | pip 套件名稱 | 版本 |
---|
PIL | pillow | 11.0.0 |
tqdm | tqdm | 4.67.1 |
yaml | PyYAML | 6.0.2 |
使用前請安裝以上模組,可以使用 requirements.txt
進行安裝。
1
| pip install -r requirements.txt
|
參數說明
參數 | 選項 | 說明 | 預設值 |
---|
--path | 必填 | 指定要壓縮的資料夾路徑 | 無 |
--compress_quality | 選填 | 壓縮品質,範圍 1–100。值越低,壓縮品質越好,但檔案可能被破壞越嚴重 | 85 |
--backup | 選填 | 是否備份原圖(True 或 False) | True |
--backup_folder | 選填 | 備份原圖存放的資料夾名稱 | original image |
--original_suffix | 選填 | 備份原圖檔名的後綴 | _original |
--skip_suffix | 選填 | 檔名含此後綴的圖片會被略過 | _skip |
--skip_original | 選填 | 是否略過已備份過的原圖(檔名含 original_suffix ) | True |
--skip_skip | 選填 | 是否略過標記為略過的圖片(檔名含 skip_suffix ) | True |
--print_image_reduced | 選填 | 是否印出每張圖片壓縮結果 | True |
--print_summary | 選填 | 是否印出壓縮摘要報表 | True |
--save_summary_to_csv | 選填 | 是否將壓縮摘要存成 CSV | True |
--summary_folder | 選填 | 壓縮摘要報表儲存資料夾 | summary |
--summary_filename | 選填 | 壓縮摘要報表檔名(不含副檔名) | report |
--config | 選填 | YAML 設定檔路徑 | config.yaml |
--lang_code | 選填 | 語言代碼,例如 zh-tw 、en | zh-tw |
--version | 選填 | 顯示程式版本資訊並退出 | 無 |
--about | 選填 | 顯示作者、版本、授權、Email、GitHub 等資訊 | 無 |
--author | 選填 | 顯示作者資訊 | 無 |
--license | 選填 | 顯示授權資訊 | 無 |
--status | 選填 | 顯示目前狀態(可依程式定義) | 無 |
--github | 選填 | 顯示 GitHub 頁面連結 | 無 |
--help | 選填 | 顯示說明文件 | 無 |
如何使用
1
| python compress_images.py --path images/
|
- 使用
config.yaml
設定檔,並關閉每張圖片的壓縮輸出
1
| python compress_images.py --config my_config.yaml --print_image_reduced False
|
1
| python compress_images.py --author
|
1
| python compress_images.py --help
|
設定
修改預設值
如欲修改設定檔預設值,或新增設定檔,請複製或修改專案根目錄下的 /config.yaml
檔案。
config.yaml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| path: "" # Folder path to process images
compress_quality: 85 # Compression quality (1-100)
backup: true # Whether to backup original images
skip_original: true # Whether to skip images already backed up
skip_skip: true # Whether to skip images marked with '_skip' in name
print_summary: true # Whether to print the compression summary report
print_image_reduced: true # Whether to print info of compressed images
save_summary_to_csv: true # Whether to save summary report as CSV file
summary_folder: summary # Folder name to save summary reports
summary_filename: report # Summary report filename (without extension)
backup_folder: original image # Folder name to store backup images
original_suffix: _original # Suffix added to original images
skip_suffix: _skip # Suffix for images to skip
lang_code: zh-tw # Language code, e.g., 'zh-tw', 'en', etc.
|
新增語言檔案
如欲修改語言檔案預設值,或新增語言檔案,請複製或修改專案根目錄下的 /language/語言.yaml
檔案。
zh-tw.yaml
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
| # language/zh-tw.yaml
general:
ask_input_path: "請輸入要壓縮的圖片資料夾路徑:"
folder_not_found: "資料夾不存在,請重新確認路徑。"
missing_param: "缺少參數 `{key}`,使用預設值:{default}"
start_processing: "共找到 {count} 張圖片,開始處理..."
processing: "壓縮中"
finished_processing: "資料夾 \"{folder}\" 處理完成!"
saved_report: "壓縮報表已儲存至:{path}"
status:
compressed: "成功壓縮"
skipped: "已備份,跳過"
skip_keyword: "跳過"
error_keyword: "錯誤"
backup_error: "備份錯誤:{error}"
compress_error: "壓縮錯誤:{error}"
report:
header_summary: "壓縮總結:"
header_ext_summary: "副檔名類型統計:"
start_time: "開始時間:{time}"
end_time: "結束時間:{time}"
elapsed: "經過時間:{elapsed}"
avg_time: "平均處理時間:{seconds:.2f} 秒"
total_images: "處理數量:{count}"
compressed_success: "成功壓縮:{count}"
skipped_backup: "已備份/跳過:{count}"
skipped_named: "因跳過名稱而跳過:{count}"
error_unreadable: "開啟錯誤/非支援:{count}"
error_failed: "壓縮錯誤:{count}"
no_avg_time: "無任何成功壓縮,無法計算平均處理時間"
size_before: "原始大小: {size:.2f} {unit}"
size_after: "壓縮後大小: {size:.2f} {unit}"
size_saved: "節省空間: {size:.2f} {unit} ({percent:.1f}%)"
ext_format: "{ext:<6}:{count} 張 節省 {savings:.2f} {unit} ({percent:.1f}%)"
KB: "KB"
MB: "MB"
GB: "GB"
csv:
section_general: "壓縮總結:"
section_ext: "副檔名類型統計:"
section_detail: "檔案詳細情況:"
fields:
key: "項目"
value: "數值"
start_time: "開始時間"
end_time: "結束時間"
elapsed: "經過時間"
avg_time: "平均處理時間 (秒)"
avg_time_unavailable: "平均處理時間"
avg_time_cannot_calculate: "無法計算"
total_images: "處理數量"
compressed: "成功壓縮"
skipped_backup: "已備份/跳過"
skipped_named: "因跳過名稱而跳過"
unreadable: "開啟錯誤/非支援"
errors: "壓縮錯誤"
size_before: "原始大小 (MB)"
size_after: "壓縮後大小 (MB)"
size_saved: "節省空間 (MB)"
size_percent: "節省百分比 (%)"
ext: "副檔名"
ext_count: "圖片數量"
ext_before: "原始大小 (MB)"
ext_after: "壓縮後大小 (MB)"
ext_saved: "節省空間 (MB)"
ext_percent: "節省百分比 (%)"
detail_path: "檔案路徑"
detail_ext: "副檔名"
detail_before: "原始大小 (KB)"
detail_after: "壓縮後大小 (KB)"
detail_percent: "節省百分比 (%)"
detail_status: "狀態"
detail_time: "處理時間"
|
授權
MIT 授權條款
版權所有 © 2025 Josh-test-lab
特此免費授權任何取得本軟體與相關文件檔案(以下簡稱「本軟體」)的人員,不受限制地處理本軟體,包括但不限於使用、複製、修改、合併、出版、散布、再授權及/或販售本軟體之副本,並允許本軟體提供者在符合以下條件下也能如此處理:
上述版權聲明及本授權聲明,應包含於本軟體之所有副本或主要部分中。
本軟體是依「現狀」提供,不附帶任何形式的明示或暗示擔保,包括但不限於對適售性、特定用途之適用性以及非侵權的擔保。在任何情況下,無論係因契約、侵權或其他行為所生,作者或版權持有人均不對任何因本軟體或其使用、其他交易而產生的任何索賠、損害或其他責任承擔任何責任。
結語
本次的專案完全是臨時起意的。身為一位業餘的程式設計玩家,在未曾接受過系統性程式訓練的情況下,能夠從零開始撰寫出一支真正能用的工具,對我而言是一件令人振奮的事。雖然這個工具稱不上完美,也有許多地方是需要重新撰寫並且完善的,但它確實解決了我在實務中遇到的問題,這種「寫給自己用」的初衷反而讓它顯得特別有價值。
在學校中,我們所接受的訓練大多都集中在如何透過縝密的邏輯進行數學推理與統計分析,而這次的實作經驗讓我意識到,這份邏輯訓練其實可以延伸並應用到更多元的領域中。我認為我不只是寫了一段程式,更是跨出了實踐的第一步,將所學透過鍵盤真真正正邁出去,獲得初步的成就。我希望這份熱忱能繼續延續下去,探索更多未知,結合更多領域,創造更多有意思且實用的工具、樂趣。
如果您對這份專案有任何建議,或程式上需要進行修正或改寫的部分,歡迎您留言。
參見