背景

下载图包的时候往往都是原图,图片大小都非常大,一张图可能得3-5M, 而我平时就是在电脑和手机上看看图片, 对分辨率、色深和细节没有太严格的要求,因此往往我会把图片有损压缩,在肉眼可接受的范围内减少图片占用空间的大小。因此找到一个合适的压图工具就必不可少。压图工具的要求有几个:

  1. 支持windows
  2. 可离线
  3. 支持多格式
  4. 可批量
  5. 运行速度快

测试比较

几款压缩工具的比较:

名称 缺点 优点 样张压缩率 速度
TinyPng 在线,单张图不超过5M,不可调参,压缩速度慢 有API,支持png和jpeg 74% 慢,上传耗时
ImageOptim 只支持mac
pingo 压缩率不高 命令行+GUI,可批量 42%
pngquant 只支持png 命令行可批量,可调参
Riot 压缩率不高 可批量,可调参,体积小,多格式 50% 一般
XnConvert 压缩率不高 GUI,可批量,可调参,多格式 51% 较快
Squoosh 不支持批量,web app无命令行 开源,可离线,可调参,压缩率高 76% 一般

尝试的工具有很多, 但是要么就是支持的类型不丰富,要么就是压缩比率不够大,最后还是选择压缩比,可离线squoosh。那么接着就要解决批量压缩图片的问题。

环境

windows 10

nodejs

python3

selenium

方法步骤

1 squoosh离线化

squoosh是Google开发的Web App, 打开网址https://squoosh.app, 安装即可离线。但是在selenium调用chrome dirver的时候无法直接使用本地的app, 只能通过服务器网址上传, 由于上传速度过慢就会导致处理效率非常低。因此首先要将squoosh离线化。

确保安装了nodejs, 下载最新版本squoosh源码, 并解压zip。进入解压文件夹,执行命令:

1
2
3
4
5
# 安装依赖
npm install
npm run build
# 启动服务
npm start

启动成功,命令行如下:

浏览器打开127.0.0.1:8080,界面如下:

2 selenium自动批量上传下载

selenium操作的chrome driver 直接打开本地的网址, 直接操作网页, 实现批量上传下载。由于服务器就是本地,因此上传速度极快。压缩好的图片会保存在源图片目录的doneBysquoosh的文件夹下。

代码如下:

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
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# coding=utf-8
# @time 2020-11-09 174254
# @author Monkey_NWPU
# @function
# @debug

import time
import os
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC


# squoosh 自动操作
def auto_squoosh():
# 列出目录下所有的图片,存在 images 这个列表中
images = os.listdir(dir_path)
# chrome driver
driver = webdriver.Chrome(chrome_options=options)
# driver.maximize_window()
# 处理当前目录下所有图片
for image in images:
# 构建图片路径
img_path = dir_path + image
# print(img_path)
# 打开 Squoosh
driver.get('http://127.0.0.1:8080/')
# 找到输入框
input_box = driver.find_element_by_xpath(
'.//input[@class="hide__2Tkcb"]')
# 输入图片路径
input_box.send_keys(img_path)
# 显性等待出现 'smaller'字样,10秒不出现则视为处理失败
locator = (
By.XPATH, './/span[@class="size-delta__1JN1e size-decrease__3Tyll"]')
# WebDriverWait(driver, 10).until(
# EC.text_to_be_present_in_element(locator, 'smaller'))
WebDriverWait(driver, 10).until(EC.presence_of_element_located(locator))
# 找到下载按钮
button = driver.find_elements_by_xpath(
'.//a[@class="download-link__1jgsx "]')
# 点击下载按钮
button[1].click()
# 等待下载完成
driver.get('chrome://downloads/')


if __name__ == "__main__":
# 图片路径
dir_path = input('Your image path: ')
dir_path = dir_path + '\\'
# 修改下载路径
options = webdriver.ChromeOptions()
prefs = {'download.prompt_for_download': False,
'download.default_directory': dir_path + 'doneBysquoosh'}
options.add_experimental_option('prefs', prefs)
# run squoosh
auto_squoosh()

效果如图:

参考资料

图片压缩:ImageOptim-CLI 与 Squoosh

ImageOptim alternatives for Windows and Linux

用 Python 操纵 Squoosh 批量压缩图片 | Yaodo Blog