Files
blog/scripts/photos_ingest.py
T
wait4xandGLM-5.3 382e56431f fix(photos): 入库压缩保留 EXIF 并补未来上传的压缩缺口
- 迁移器与新增 photos_ingest.py 压缩时显式 exif= 传参(PIL 重存默认
  剥离——此前 21 张已全部丢 EXIF,图库参数条构建期数据源被抽空)
- exif=None 会使 PIL JPEG 保存 len(None) 崩,改条件传参
- photos_ingest.py:幂等入库处理器(长边 2400/q86,>1.5M 才动),
  堵住 gitea/本地上传原图直入仓的缺口(196M 事故成因)
- 重跑迁移:19/21 带 EXIF(2 张原图本无),体积 9.7M

验证: pnpm astro build 11 页 exit 0;EXIF 保留计数 19/21

Spec: none (Phase 2 归档后的独立小修:EXIF 修复 + ingest 补缺)

Co-authored-by: GLM-5.3
2026-10-25 09:01:07 +08:00

48 lines
1.7 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env python3
"""照片入库处理器:把 content/photos/ 下超限图片压缩到站内规范。
为什么存在:gitea web/本地上传的是原图(曾发生 196M/21 张入仓事故,
见 git log aea21c8 的重写说明);sharp 只派生 dist 缩略图不管仓内体积。
工作流:上传照片到 content/photos/(顺带跑一次 sidecar 生成或手写)后、
git commit 前执行本脚本;幂等,已在规范内的文件原样跳过(零 diff)。
规范与迁移器一致:长边 ≤2400px、JPEG q86(scripts/migrate/photos_migrate.py)。
"""
import sys
from pathlib import Path
PHOTOS = Path("content/photos")
MAX_EDGE = 2400
QUALITY = 86
# 跳过阈值:小于此字节数的 jpg 视为已处理过(2400px q86 成片通常 200KB-1MB)
SKIP_BELOW_BYTES = 1_500_000
def main() -> int:
from PIL import Image
changed, skipped = [], 0
for jpg in sorted(PHOTOS.glob("*.jpg")):
size = jpg.stat().st_size
if size < SKIP_BELOW_BYTES:
skipped += 1
continue
img = Image.open(jpg)
# EXIF 显式保留:重存默认剥离会抽走图库参数条的构建期数据源
exif = img.info.get("exif")
if img.mode not in ("RGB", "L"):
img = img.convert("RGB")
img.thumbnail((MAX_EDGE, MAX_EDGE))
kwargs = {"exif": exif} if exif else {}
img.save(jpg, "JPEG", quality=QUALITY, optimize=True, **kwargs)
changed.append((jpg.name, size, jpg.stat().st_size))
for name, before, after in changed:
print(f" compressed: {name} {before/1e6:.1f}M -> {after/1e6:.2f}M")
print(f"photos ingest: {len(changed)} compressed, {skipped} skipped (within spec)")
return 0
if __name__ == "__main__":
sys.exit(main())