60 lines
2.1 KiB
Python
60 lines
2.1 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
压缩公众号配图
|
|
目标:每张PNG < 80KB,保持清晰度
|
|
"""
|
|
|
|
import os
|
|
from PIL import Image
|
|
|
|
IMAGES_DIR = "/root/.openclaw/workspaces/yzr-yxl/projects/yu-zhi-ran/content/publishing/images"
|
|
OUTPUT_DIR = "/root/.openclaw/workspaces/yzr-yxl/projects/yu-zhi-ran/content/publishing/images_compressed"
|
|
|
|
os.makedirs(OUTPUT_DIR, exist_ok=True)
|
|
|
|
def compress_png(input_path, output_path, target_kb=80):
|
|
img = Image.open(input_path)
|
|
|
|
# 如果图片较大,适当缩小(保持长宽比)
|
|
max_width = 1200
|
|
if img.width > max_width:
|
|
ratio = max_width / img.width
|
|
new_size = (max_width, int(img.height * ratio))
|
|
img = img.resize(new_size, Image.Resampling.LANCZOS)
|
|
print(f" 缩放: {img.width}x{img.height}")
|
|
|
|
# 尝试不同压缩级别保存
|
|
for optimize in [True, False]:
|
|
for quality in [85, 80, 75, 70]:
|
|
img.save(output_path, format='PNG', optimize=optimize, compress_level=6, quality=quality)
|
|
size_kb = os.path.getsize(output_path) / 1024
|
|
if size_kb <= target_kb:
|
|
return size_kb, quality, optimize
|
|
# 如果还是大,强制用最高压缩
|
|
img.save(output_path, format='PNG', optimize=True, compress_level=9)
|
|
return os.path.getsize(output_path) / 1024, 9, True
|
|
|
|
if __name__ == "__main__":
|
|
files = sorted([f for f in os.listdir(IMAGES_DIR) if f.endswith('.png')])
|
|
print(f"开始压缩 {len(files)} 张图片...\n")
|
|
|
|
total_before = 0
|
|
total_after = 0
|
|
|
|
for f in files:
|
|
inp = os.path.join(IMAGES_DIR, f)
|
|
out = os.path.join(OUTPUT_DIR, f)
|
|
size_before = os.path.getsize(inp) / 1024
|
|
total_before += size_before
|
|
|
|
size_after, quality, opt = compress_png(inp, out)
|
|
total_after += size_after
|
|
|
|
status = "✅" if size_after <= 80 else "⚠️"
|
|
print(f"{status} {f}")
|
|
print(f" {size_before:5.1f}KB → {size_after:5.1f}KB (q={quality}, opt={opt})")
|
|
|
|
print(f"\n总计: {total_before:.1f}KB → {total_after:.1f}KB")
|
|
print(f"压缩率: {(1-total_after/total_before)*100:.1f}%")
|
|
print(f"\n压缩文件已保存至: {OUTPUT_DIR}")
|