使用 TinyPNG 接口实现一个压缩图片小 Demo
起因
起因是这样的,其实很简单,就是之前的博客图片都是交给图床去接管的,用过 GitHub 图床,用过七牛,用过腾讯云,还有又拍云、B2 云、甚至还有最开始时候的 Gitee,还有一大堆如同 smms 这种第三方运营的专业图床。但随着时间的流逝,谁也不能保证说永恒,GitHub 访问慢, jsDelivr 被墙,CloudFlare 被联通墙,smms 被墙,弄了个 smms.app 的新站点出来依旧是访问不理想,但即便有 hello 图床这种免费快速的图床,但又害怕哪天就突然停运了。
要不这样吧,一份放本地,一份统一一个图床,所以在此之前需要对之前的图片进行收集,因为有些链接都已经失效了,所以还是得手工筛查一遍,而且为了存储的质量,选择了大名鼎鼎的 TinyPNG 做图片压缩,节约空间是小事,提高访问速度这是真的。
经过
1、账号注册
首先需要说明的是,图片的压缩服务是交由 TinyPNG 来做处理的,所以需要上传文件到云端,但好在官方给了 API,所以只需要去注册一个账号,申请一个 key,官方地址是这个 ——TinyPNG – 智能压缩您的 WebP、JPEG 和 PNG 图片 (tinify.cn)
首先是点击开发者 API,填写名字和邮箱,点击 Get your API key 即可收到用户登录的邮件
登录后在个人中心可以点击 API,在这个页面可以生成自己的 API
2、写代码
因为 API 接口支持本地图片和 URL 以及 Buff 的形式,但我只实现了两个功能,分别是本地图片和 URL,具体参考官方文档 ——TinyPNG – API Reference (tinify.cn)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
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94import hashlib
import os
import random
import shutil
import tkinter as tk
from tkinter import filedialog
from pathlib import Path
import tinify
import win32api
import win32con
def url():
source = tinify.from_url(input())
source.to_file("newFile")
with open("newFile", 'rb') as f:
data = f.read()
new_name = str.upper(hashlib.md5(data).hexdigest()) + "png"
os.rename("newFile", new_name)
def init_key():
if os.path.exists("key.txt"):
with open("key.txt", 'r') as f:
data = f.read()
print("-------------------------\n\n你的Key文件内容如下:" + data + "\n\n-------------------------------")
return data
else:
print("未读取到目录下的Key.txt文件,现在为你创建")
with open("key.txt", 'w') as f:
f.write(input("请输入Key,Key可以在TinyPng免费申请,多个Key用|分开:"))
win32api.SetFileAttributes("./key.txt", win32con.FILE_ATTRIBUTE_HIDDEN)
return init_key()
def random_key():
return keys[random.randint(0, len(keys) - 1)]
def from_file():
root = tk.Tk() # 创建一个Tkinter.Tk()实例
root.withdraw() # 将Tkinter.Tk()实例隐藏
f_path = filedialog.askopenfilename(title="选择需要压缩的文件",
filetypes=[("可压缩图像", ".jpg .jpeg .jpe .jfif .webp .png")],
defaultextension=".png")
path = Path(f_path)
parents_dir = str(path.parents[0])
suffix = str(path.suffix)
temp_path = parents_dir + '\\tempFile' + suffix
source = tinify.from_file(f_path)
source.to_file(temp_path)
with open(temp_path, 'rb') as f:
data = f.read()
md5_path = parents_dir + '\\' + str.upper(hashlib.md5(data).hexdigest()) + suffix
if not os.path.exists(md5_path):
os.rename(temp_path, md5_path)
print("压缩完成,文件名为" + md5_path)
else:
print("文件已存在")
os.remove(f_path)
def from_url(link):
root = tk.Tk() # 创建一个Tkinter.Tk()实例
root.withdraw() # 将Tkinter.Tk()实例隐藏
suffix = '.' + link.split('.')[-1]
temp_file = "temp" + suffix
source = tinify.from_url(link)
source.to_file(temp_file)
with open(temp_file, 'rb') as f:
data = f.read()
md5 = str.upper(hashlib.md5(data).hexdigest())
full_name = md5 + suffix
if not os.path.exists(full_name):
os.rename(temp_file, full_name)
save_path = filedialog.asksaveasfilename(title="选择保存路径",
filetypes=[("可压缩图像", ".jpg .jpeg .jpe .jfif .webp .png")],
defaultextension=suffix, initialfile=md5)
if not os.path.exists(save_path):
shutil.move(full_name, save_path)
print("压缩已完成,路径为" + save_path)
if __name__ == '__main__':
keys = init_key().split("|")
while True:
tinify.key = random_key()
i = input("直接回车选择文件,输入网站从链接上传")
if i == "":
from_file()
else:
from_url(i)
项目部分操作运用到了 tk 库,主要是方便了选择文件和保存文件,同时还对文件进行了 MD5 校验,文件名就是图片的 MD5 值
展示结果
完全能够完成压缩的工作,再看看压缩率
惊人的十倍压缩率,那会不会被压得太糊了呢?下做对比
这是压缩前的
这是压缩后的
我个人感觉是可以完全接受的,毕竟十倍的压缩率呢