Python优化图床图片大小
Joking引言
之前因为第一次接触博客,所以没注意到图床图片的大小会影响网站的加载速度,上传图片的时候没进行压缩,导致一堆文章的封面都有几mb。注意到的时候又因为之前上传的图片在多处被使用,一个个查找+重新上传图床实在太麻烦,所以一直丢着没改。今晚突然心血来潮,遂改之。
原图片优化
webp是谷歌于2010年提出了一种新的图片压缩格式,这种格式的图片有损条件下支持透明通道。据官方实验显示:无损WebP相比PNG减少26%大小;有损WebP在相同的SSIM(Structural Similarity Index,结构相似性)下相比JPEG减少25%~34%的大小;有损WebP也支持透明通道,大小通常约为对应PNG的1/3。
非常适合博客图片压缩有没有?
把原图床图片全部下载下来,用Python脚本把.jpg和.png格式的图片转换成webp格式:
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
| """ 把当前目录及其子目录下所有 .jpg / .png 转成 .webp 默认质量 85,保留目录结构,跳过已存在的 .webp """ import os from pathlib import Path from PIL import Image
QUALITY = 85 DELETE_ORIGINAL = False
def convert_image(src_path: Path): dst_path = src_path.with_suffix('.webp') if dst_path.exists(): return try: with Image.open(src_path) as im: im = im.convert('RGBA') if im.mode not in ('RGB', 'RGBA') else im im.save(dst_path, 'WEBP', quality=QUALITY, method=6) print(f"✓ {src_path} -> {dst_path}") if DELETE_ORIGINAL: src_path.unlink() except Exception as e: print(f"✗ 转换失败 {src_path}: {e}")
def main(): exts = ('*.jpg', '*.jpeg', '*.png') for ext in exts: for path in Path('.').rglob(ext): convert_image(path)
if __name__ == '__main__': main()
|
这样我们就得到了优化后的原图片
重新上传
由于我是用Github作图床,所以批量重新上传还比较方便,只要随便找个IDE登录Github账号,拉取图床仓库到本地,然后就能在本地随意增删改查图床图片啦。最后提交并推送,大功告成。

替换博客项目文本
最后要将博客项目里引用的原图片链接全部替换成优化后的.webp后缀的图片链接,用Python脚本递归扫描整个项目中指定的文件类型,并将无后缀、.jpg、.jpeg、.png后缀的图片链接替换成.webp后缀的。因为我用的是自己的域名,所以查找起来还是比较方便的。
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
| """ 递归扫描目录,把裸露的 pic.joking7.com 链接: - 无后缀 → 加 .webp - .jpg/.png → 改 .webp 其余不变,**直接覆盖原文件,不备份**。 """
import os import re from pathlib import Path
TEXT_EXTS = {'.md', '.txt', '.html', '.htm', '.xml', '.json', '.yaml', '.yml'} URL_RE = re.compile(r'https?://pic\.joking7\.com/[^\s"\'<>)\]]*', re.I)
def fix(url: str) -> str: base, _, ext = url.rpartition('.') if '/' in ext: return url + '.webp' if ext.lower() in {'jpg', 'png'}: return base + '.webp' return url
def process(path: Path): txt = path.read_text(encoding='utf-8', errors='ignore') new_txt, n = URL_RE.subn(lambda m: fix(m.group(0)), txt) if n: path.write_text(new_txt, encoding='utf-8') print(f'✅ {path} 已更新 {n} 处')
def main(root='.'): for p in Path(root).rglob('*'): if p.suffix.lower() in TEXT_EXTS: process(p)
if __name__ == '__main__': import sys main(sys.argv[1] if len(sys.argv) > 1 else '.')
|
效果
忘了截优化之前的图了。。。

主页加载的数据量从十几MB优化到5.7MB,大功告成 ^ ^