import subprocess
import shutil
import webbrowser
import sys
import argparse
import platform
INPUT_DIR = "input"
OUTPUT_DIR = "output"
quality_settings = {
"screen": "/screen",
"ebook": "/ebook",
"printer": "/printer",
"prepress": "/prepress"
}
def check_ghostscript():
gs = shutil.which("gswin64c") or shutil.which("gs")
if gs is None:
print("❌ [未安裝Ghostscript]")
if platform.system() == "Windows":
print("👉 請下載 Windows 版本 (gswin64)")
else:
print("👉 請下載對應系統版本")
print("👉 即將開啟下載頁面...")
webbrowser.open("https://www.ghostscript.com/download/gsdnld.html")
print("⚠ 若已安裝,請確認 Ghostscript 已加入 PATH")
sys.exit(1)
return gs
def compress_pdf(gs_command, input_path, output_path, quality):
cmd = [
gs_command,
"-sDEVICE=pdfwrite",
"-dCompatibilityLevel=1.4",
f"-dPDFSETTINGS={quality_settings.get(quality, '/ebook')}",
"-dNOPAUSE",
"-dQUIET",
"-dBATCH",
f"-sOutputFile={output_path}",
input_path
]
result = subprocess.run(cmd, capture_output=True, text=True)
if result.returncode != 0:
raise RuntimeError(result.stderr)
def process_file(gs_command, file, quality):
input_path = os.path.join(INPUT_DIR, file)
name, ext = os.path.splitext(file)
output_path = os.path.join(OUTPUT_DIR, f"{name}_compressed{ext}")
compress_pdf(gs_command, input_path, output_path, quality)
original_size = os.path.getsize(input_path) / 1024
compressed_size = os.path.getsize(output_path) / 1024
print(f"✔ {file}")
print(f" 原始: {original_size:.2f} KB")
print(f" 壓縮: {compressed_size:.2f} KB")
if compressed_size >= original_size:
print(" ⚠ 壓縮後反而變大,已刪除壓縮檔\n")
os.remove(output_path)
return
reduction = original_size - compressed_size
ratio = (1 - compressed_size / original_size) * 100
print(f" 減少: {reduction:.2f} KB")
print(f" 壓縮率: {ratio:.2f}%\n")
def main():
parser = argparse.ArgumentParser(description="PDF 批次壓縮工具")
parser.add_argument(
"--quality",
choices=quality_settings.keys(),
default="ebook",
help="壓縮品質 (預設: ebook)"
)
args = parser.parse_args()
gs_command = check_ghostscript()
if not os.path.exists(INPUT_DIR):
os.makedirs(INPUT_DIR)
print(f"📁 已建立資料夾: {INPUT_DIR},請放入 PDF 後重新執行")
return
if not os.path.exists(OUTPUT_DIR):
os.makedirs(OUTPUT_DIR)
files = [f for f in os.listdir(INPUT_DIR) if f.lower().endswith(".pdf")]
if not files:
print("📂 input 資料夾內沒有 PDF")
return
for file in files:
try:
process_file(gs_command, file, args.quality)
except Exception as e:
print(f"✖ 失敗: {file}")
print(e)
print()
if __name__ == "__main__":
main()