-
- Python批量压缩图片(TinyPNG)
-
- 什么是TinyPNG?
- Mac客户端
- 申请/查看Developer API
- 环境准备
- Python脚本
- 执行批量压缩
- 完整示例
-
- Python批量压缩图片(TinyPNG)
Python批量压缩图片(TinyPNG)
什么是TinyPNG?
TinyPNG提供了PNG图片的“几乎无损”压缩服务。详细介绍TinyPNG
Mac客户端
Mac客户端下载地址
网上大多都是通过Python脚本实现,这里做一个简单的总结。
申请/查看Developer API
如果你是免费用户,那么每个developer key最多只能压500次
,可通过多注册几个邮箱的方式解决次数的限制。
这里邮箱不支持QQ邮箱
如果你之前有使用邮箱申请过API Key
可以登录来查看邮箱关联的API Key
TinyPNG平台没有密码机制自能发送邮件来关联登录
环境准备
以下为笔者测试通过的Mac环境
1、Python版本2.7.10
(Mac默认有安装Python)
查看Python 版本python -V
,如果没有安装Mac电脑建议使用brew包管理工具安装brew install python
2、pip版本为10.0.1
pip安装参考文档
curl https://bootstrap.pypa.io/get-pip.py -o get-pip.pypython get-pip.py
3、安装Python的tinify模板库
pip install --upgrade tinify
Python脚本
新建tinypng.py
文件复制以下脚本并保存
#!/usr/bin/env python
# -*- coding: UTF-8 -*-import os
import sys
import csv
import os.path
import tinify
from PIL import Image
from optparse import OptionParser
#请替换为自己申请的Key
tinify.key = ""
png_path = []
png_path_compressed = []def get_png_path(inputPath):for p in os.listdir(inputPath):temp_path = os.path.join(inputPath,p)if os.path.isdir(temp_path):get_png_path(temp_path)else:if os.path.splitext(p)[1] == '.png' or os.path.splitext(p)[1] == 'jpg' or os.path.splitext(p)[1] == 'jpeg':print "PNG File:",os.path.join(inputPath,p)png_path.append(os.path.join(inputPath,p)) def compress_core(inputFile, outputFile, img_width):source = tinify.from_file(inputFile)if img_width is not None:resized = source.resize(method = "scale", width = img_width)resized.to_file(outputFile)else:source.to_file(outputFile)def compress_path(path, width):print "compress_path-------------------------------------"if not os.path.isdir(path):print "这不是一个文件夹,请输入文件夹的正确路径!"returnelse:fromFilePath = path # 源路径toFilePath = path+"/tiny" # 输出路径print "fromFilePath=%s" %fromFilePathprint "toFilePath=%s" %toFilePathfor root, dirs, files in os.walk(fromFilePath):print "root = %s" %rootprint "dirs = %s" %dirsprint "files= %s" %filesfor name in files:fileName, fileSuffix = os.path.splitext(name)if fileSuffix == '.png' or fileSuffix == '.jpg' or fileSuffix == '.jpeg':toFullPath = toFilePath + root[len(fromFilePath):]toFullName = toFullPath + '/' + nameif os.path.isdir(toFullPath):passelse:os.mkdir(toFullPath)compress_core(root + '/' + name, toFullName, width)break # 仅遍历当前目录# 仅压缩指定文件
def compress_file(inputFile, width):print "compress_file-------------------------------------"if not os.path.isfile(inputFile):print "这不是一个文件,请输入文件的正确路径!"returnprint "file = %s" %inputFiledirname = os.path.dirname(inputFile)basename = os.path.basename(inputFile)fileName, fileSuffix = os.path.splitext(basename)if fileSuffix == '.png' or fileSuffix == '.jpg' or fileSuffix == '.jpeg':mkdir(dirname+"/tiny");png_path_compressed.append(dirname+"/tiny/"+basename)compress_core(inputFile, dirname+"/tiny/"+basename, width)else:print "不支持该文件类型!"def mkdir(path): folder = os.path.exists(path) if not folder: #判断是否存在文件夹如果不存在则创建为文件夹 os.makedirs(path) #makedirs 创建文件时如果路径不存在会创建这个路径 print "--- new folder... ---" print "--- OK ---" else: print "--- There is this folder! ---" def run(file, dir=None, width=None):if file is not None:print "仅压缩一个文件!"compress_file(file, width) # 仅压缩一个文件passelif dir is not None:print "压缩指定目录下的文件!"compress_path(dir, width) # 压缩指定目录下的文件passelse:print "压缩当前目录下的文件!"compress_path(os.getcwd(), width) # 压缩当前目录下的文件def get_compressed_result():for png in png_path:run(os.path.abspath(png))rows = []row = ()for i in range(len(png_path)):img = Image.open(png_path[i])imgSize = img.sizebefore_compressed = os.stat(png_path[i]).st_sizeafter_compressed = os.stat(png_path_compressed[i]).st_sizeprint png_path[i],before_compressed,after_compressed,(before_compressed - after_compressed) *1.0/ before_compressedif imgSize[0] * imgSize[1] > 1024* 1024:too_large_scale = "True"else:too_large_scale = "False"row = (png_path[i],before_compressed,after_compressed,(before_compressed - after_compressed) *1.0/ before_compressed,imgSize[0],imgSize[1],too_large_scale)rows.append(row)header = [u'Path',u'before_compressed',u'after_compressed',u'compression_rate',u'width',u'height',u'too_large_scale']with open('compressed.csv','wb') as f:f_csv = csv.writer(f)f_csv.writerow(header) f_csv.writerows(rows)if __name__ == "__main__":usage = '''python tinypng.py [options]-example: python tinypng.py -d xxx '''parser = OptionParser(usage) parser.add_option('-d', dest='_path', help=u'(必选)指定游戏脚本路径')(options, args) = parser.parse_args()if not options._path:print '\n -d 参数必须设置!'print usagesys.exit(1) get_png_path(options._path)get_compressed_result()
执行批量压缩
进入tinypng.py
文件所在目录执行以下命令
python tinypng.py -d ya
-d 后面为要压缩图片的文件夹路径
完整示例
要压缩的图片在/Users/Javen/Documents/dev/img/ya
中,tinypng.py
文件在/Users/Javen/Documents/dev/img/
中,如下图所示
执行压缩命令
压缩后效果图