优化图床图片大小

引言

之前因为第一次接触博客,所以没注意到图床图片的大小会影响网站的加载速度,上传图片的时候没进行压缩,导致一堆文章的封面都有几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
#!/usr/bin/env python3
"""
把当前目录及其子目录下所有 .jpg / .png 转成 .webp
默认质量 85,保留目录结构,跳过已存在的 .webp
"""
import os
from pathlib import Path
from PIL import Image

QUALITY = 85 # 0-100,数字越大越清晰、体积越大
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账号,拉取图床仓库到本地,然后就能在本地随意增删改查图床图片啦。最后提交并推送,大功告成。

image-20250806234854980

替换博客项目文本

最后要将博客项目里引用的原图片链接全部替换成优化后的.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
#!/usr/bin/env python3
"""
递归扫描目录,把裸露的 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'}: # .jpg/.png → .webp
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 '.')

效果

忘了截优化之前的图了。。。

image-20250806235629567

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