目錄

圖片壓縮工具

封面圖片由 ChatGPT 生成。

前言

在平時建立網站頁面時,我們會發現有時候有些頁面需要讀取一段時間才能出現,而有些頁面卻沒有。經過比較不同網頁後得出一個結論,網頁內的圖片如果大小過大,會造成網頁讀取速度較慢,因此萌生出要找到一款能夠壓縮目前網站目錄下所有圖片工具。

但找來找去,網路上都沒有找到合適的應用程式,最後決定自己製作一款能夠壓縮所有圖片的程式。

需求

在開始製作前,我確認自己所需要的需求如下:

  • 能夠調節壓縮圖片的程度。
  • 能夠選擇是否要保留原始圖片在原目錄,方便以後重新調用。
  • 能夠略過一些不必要的圖片,或者是已經壓縮過的圖片。
  • 能夠產生壓縮報表,確定此次節省的空間。

而以下工具便是基於上述中目前所遇到的需求建立的。本文並不琢磨於如何進行此工具的開發,僅介紹此工具的用法。如國對此工具有任何建議、需要修正的部分,歡迎您留言指教。

專案 Image Compression Tool

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 套件名稱版本
PILpillow11.0.0
tqdmtqdm4.67.1
yamlPyYAML6.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_suffixTrue
--skip_skip選填是否略過標記為略過的圖片(檔名含 skip_suffixTrue
--print_image_reduced選填是否印出每張圖片壓縮結果True
--print_summary選填是否印出壓縮摘要報表True
--save_summary_to_csv選填是否將壓縮摘要存成 CSVTrue
--summary_folder選填壓縮摘要報表儲存資料夾summary
--summary_filename選填壓縮摘要報表檔名(不含副檔名)report
--config選填YAML 設定檔路徑config.yaml
--lang_code選填語言代碼,例如 zh-twenzh-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

特此免費授權任何取得本軟體與相關文件檔案(以下簡稱「本軟體」)的人員,不受限制地處理本軟體,包括但不限於使用、複製、修改、合併、出版、散布、再授權及/或販售本軟體之副本,並允許本軟體提供者在符合以下條件下也能如此處理:

上述版權聲明及本授權聲明,應包含於本軟體之所有副本或主要部分中。

本軟體是依「現狀」提供,不附帶任何形式的明示或暗示擔保,包括但不限於對適售性、特定用途之適用性以及非侵權的擔保。在任何情況下,無論係因契約、侵權或其他行為所生,作者或版權持有人均不對任何因本軟體或其使用、其他交易而產生的任何索賠、損害或其他責任承擔任何責任。

提示
授權條款以 Github 儲存庫中的版本為準。

結語

本次的專案完全是臨時起意的。身為一位業餘的程式設計玩家,在未曾接受過系統性程式訓練的情況下,能夠從零開始撰寫出一支真正能用的工具,對我而言是一件令人振奮的事。雖然這個工具稱不上完美,也有許多地方是需要重新撰寫並且完善的,但它確實解決了我在實務中遇到的問題,這種「寫給自己用」的初衷反而讓它顯得特別有價值。

在學校中,我們所接受的訓練大多都集中在如何透過縝密的邏輯進行數學推理與統計分析,而這次的實作經驗讓我意識到,這份邏輯訓練其實可以延伸並應用到更多元的領域中。我認為我不只是寫了一段程式,更是跨出了實踐的第一步,將所學透過鍵盤真真正正邁出去,獲得初步的成就。我希望這份熱忱能繼續延續下去,探索更多未知,結合更多領域,創造更多有意思且實用的工具、樂趣。

如果您對這份專案有任何建議,或程式上需要進行修正或改寫的部分,歡迎您留言

參見