在网上有很多使用 python 的 pillow 库进行图片压缩的教程,使用简单,但是压缩效果存在明显的色彩不自然,这是因为 pillow 库采取的压缩算法没有优化的问题。
这个系列实现一款简单的压缩工具,使用 pngquant 有损压缩,压缩率高达 80%, 而且压缩后的图片没有明显差异。
上一篇使用了 pngquant 图片压缩工具进行压缩,并通过 click 命令行工具构建了 picom 包。这篇的主要功能是实现图片上传。
图片上传功能的实现
石头小说 www.10tou.com通过 pngquant 压缩图片后,得到一个 -fs8.png
为后缀的图片。想要把图片上传到云端,只需要把这个文件通过 API 发送给图片存储服务商就可以了。
先实现 sm.ms 网站的图片上传。官方提供了 API 文档,照着文档传入参数就可以搞定,so easy.
![image.png](https://i-blog.csdnimg.cn/blog_migrate/eeac2026d8b29abcc9495e986576a1e8.png)
上传接口的参数说明:
- content-type 为 multipart/form-data ;
- Authorization 为可选项,当不需要用户管理时,可以不填;
- 传入文件的参数名为 smfile。
对应的 python 代码:
api_addr = 'https://sm.ms/api/v2/upload'
files = {
"smfile": open(file, 'rb')
}
res = requests.post(url, files=files)
获取上传的图片地址
文件上传完毕以后,需要通过 API 的响应结果得到图片的 URL。 sm.ms 的响应结果包含 2 种情况:
- 当图片已经上传过一次,会通过图片的 hash 值判断出重复。响应中的 code 为 image_repeated, 可以通过 images 取得之前已存在的图片地址。
{
"code": "image_repeated",
"images": "https:..."
}
- 当图片是第一次上传,code 为 success, 可以通过 data 中的 url 获取图片地址。
{
"code": "success",
"data": {
"url": "https:..."
}
}
所以在上传的函数中添加判断,获取图片 url:
resp = res.json()
code = resp.get('code')
if code == 'image_repeated':
url = resp["images"]
return url
elif code == 'success':
return resp["data"]["url"]
因为有时候并不是上传单张图片,而是要上传整个文件夹下面的图片,一次性需要处理多张图片的上传操作,所以可以共用一个 session, 对应的上传图片类:
![image.png](https://i-blog.csdnimg.cn/blog_migrate/ad7ca17699bcec43905cfd303cceb0a1.png)
为命令行添加 --upload
可选参数
现在我可以选择是否把图片上传到网上,如果需要上传,就添加 --upload
参数;如果不需要上传,就不传这个命令行参数:
picom elephant.png -f --upload
增加 --upload
可选参数只需要在 cli 函数上多加一个 option, 然后添加上传代码就可以了:
![image.png](https://i-blog.csdnimg.cn/blog_migrate/3d25e79526b36e9310e3848e673ea5e4.png)
最后得到的运行结果:
![image.png](https://i-blog.csdnimg.cn/blog_migrate/924e25ecb615a7efdc705aac802c51db.png)
通过 yaml 记录以及上传过的图片地址
上面上传的图片地址是在命令行显示的,如果一次性使用还好,但是如果需要重复使用就需要把图片的 URL 保存起来。
sm.ms 的账号功能可以管理已经上传的图片。所以如果有 sm.ms 的账号,就不需要这个保存的功能。 但是如果不想去注册账号,有一个委曲求全的办法,就是在当前文件夹创建一个名为 uploaded_img.yaml 的文件,把已经上传的图片地址保存起来。
可以通过新建一个选项 --record
来选择是否记录在本地。python 可以通过 pyyaml 库操作 yaml 文件,存储上传的图片数据。 也可以通过 json 格式保存,大致的格式是这样的:
{
"upload":[
{
"name": "elephant.png",
"url" : "http://img-server/ofos.png"
}
]
}
因为这个功能不是特别重要,甚至可以说鸡肋,就不贴代码了。
总结
![picom-upload](https://imgkr.cn-bj.ufileos.com/4a54f8af-33b8-4113-983c-f280b1923b7a.gif)
上传图片功能非常简单,只需要使用 requests 库的基础操作就可以完成各个图床服务商的上传操作。如果觉得 requests 库的操作比较慢,可以采用 aiohttp 进行异步传输。 这个工具暂且不考虑加快传输速度,因为现在的图床服务很多都是小本经营,没什么盈利能力,为了能提供长久服务,还是尽量少的给别人压力。