92 lines
2.8 KiB
Python
92 lines
2.8 KiB
Python
#!/usr/bin/env python3
|
|
"""Re-compress existing .webp images with optimized parameters to reduce file size.
|
|
|
|
Usage:
|
|
python optimize_webp.py
|
|
|
|
Backups originals to a .bak/ folder before overwriting.
|
|
"""
|
|
|
|
from pathlib import Path
|
|
from PIL import Image
|
|
import shutil
|
|
|
|
BASE_DIR = Path(__file__).resolve().parent
|
|
PUBLIC_DIR = BASE_DIR / "public"
|
|
|
|
# Directories to optimize
|
|
TARGET_DIRS = [
|
|
PUBLIC_DIR / "mobile-image",
|
|
PUBLIC_DIR / "desketop-image",
|
|
]
|
|
|
|
# Compression parameters
|
|
QUALITY = 80
|
|
METHOD = 6
|
|
|
|
|
|
def optimize_webp(src_path: Path, backup_dir: Path) -> tuple[int, int]:
|
|
"""Re-encode a single WebP image with optimized quality settings.
|
|
Returns (original_size, new_size) in bytes.
|
|
"""
|
|
original_size = src_path.stat().st_size
|
|
backup_path = backup_dir / src_path.name
|
|
|
|
# Backup original
|
|
shutil.copy2(src_path, backup_path)
|
|
|
|
# Re-encode
|
|
img = Image.open(src_path)
|
|
# For RGB/RGBA, keep as-is; for other modes, convert to RGBA
|
|
if img.mode not in ("RGB", "RGBA"):
|
|
img = img.convert("RGBA")
|
|
img.save(src_path, format="WEBP", quality=QUALITY, method=METHOD)
|
|
|
|
new_size = src_path.stat().st_size
|
|
return original_size, new_size
|
|
|
|
|
|
def main():
|
|
total_original = 0
|
|
total_new = 0
|
|
total_files = 0
|
|
|
|
for target_dir in TARGET_DIRS:
|
|
if not target_dir.exists():
|
|
print(f"Skip: {target_dir} not found")
|
|
continue
|
|
|
|
backup_dir = target_dir.parent / (target_dir.name + ".bak")
|
|
backup_dir.mkdir(exist_ok=True)
|
|
|
|
print(f"\n[DIR] Optimizing: {target_dir}")
|
|
print("-" * 50)
|
|
|
|
for webp_file in sorted(target_dir.glob("*.webp"), key=lambda p: p.name.lower()):
|
|
original_size, new_size = optimize_webp(webp_file, backup_dir)
|
|
total_original += original_size
|
|
total_new += new_size
|
|
total_files += 1
|
|
|
|
reduction = original_size - new_size
|
|
pct = (reduction / original_size) * 100 if original_size else 0
|
|
status = "OK" if new_size < original_size else "WARN"
|
|
print(
|
|
f" [{status}] {webp_file.name:20s} "
|
|
f"{original_size/1024:8.1f} KB -> {new_size/1024:8.1f} KB "
|
|
f"(-{reduction/1024:8.1f} KB, {pct:5.1f}%)"
|
|
)
|
|
|
|
print("\n" + "=" * 60)
|
|
print(f" Total files: {total_files}")
|
|
print(f" Original size: {total_original/1024/1024:.2f} MB")
|
|
print(f" New size: {total_new/1024/1024:.2f} MB")
|
|
print(f" Saved: {(total_original - total_new)/1024/1024:.2f} MB ({(total_original - total_new)/total_original*100:.1f}%)")
|
|
print("=" * 60)
|
|
print(f"\nBackups saved to: {PUBLIC_DIR}/mobile-image.bak/ and desketop-image.bak/")
|
|
print("If quality is not acceptable, restore from backup folders.")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|