使用Python快速压缩目录中图片
脚本语言
#coding:utf-8
import Image
import os
import logging
import sqlite3
from PIL import ImageFile
ImageFile.LOAD_TRUNCATED_IMAGES = True
#全局变量 数据库链接
global cx
#全局变量 数据库链接游标
global cu
#全局变量 创建表单标识
global createTableFlag
##########################################
# @function 判断是否为图片
# @param srcFile 待压缩图片
##########################################
def picIsCorrect(fileSuffix):
if fileSuffix == ".png" or fileSuffix == ".jpg" or fileSuffix == ".jpeg":
return True
else:
return False
##########################################
# @function 判断图片大小是否需要压缩
# @param srcFile 待压缩图片
##########################################
def picIsBig(srcFile):
size = os.path.getsize(srcFile)/1024
if size > 0 :
return True
else:
return False
##########################################
# @function 判断图片大小是否被压缩过
# @description 如果图片信息存在于数据库中,则表明图片被压缩过,不需要再次压缩
# @param basename 待压缩图片名称
##########################################
def picIsCompressed(basename , dstFile):
if selectTableCompressLog(basename , dstFile):
#print(" images is already compressed which named " + basename + ' or path equals ' + dstFile)
return True
else:
return False
##########################################
# @function 创建记录压缩信息的表单
# @description 如果图片信息存在于数据库中,则表明图片被压缩过,不需要再次压缩
##########################################
def createTableCompressLog():
#全局变量 创建表单标识
global createTableFlag
if createTableFlag :
try:
create_tb_cmd='''
create table if not exists compresslog (id varchar(64) primary key , name varchar(64) UNIQUE , path varchar(1024) UNIQUE , size integer , org_size integer , status integer)
'''
#主要就是上面的语句
cu.execute(create_tb_cmd)
createTableFlag = False
except:
logging.info(" table compresslog maybe exist , create table compresslog fail ")
createTableFlag = False
##########################################
# @function 查询表单中图片信息是否存在
# @description 如果图片信息存在于数据库中,则表明图片被压缩过,不需要再次压缩
##########################################
def selectTableCompressLog(basename , dstFile):
#进行建表语句
createTableCompressLog()
#打开游标
cu.execute("select * from compresslog where id = '" + basename + "'" + " or path = '" + dstFile + "'")
#执行查询操作
rows = cu.fetchall()
if len(rows) > 0:
print(" images is already compressed which named " + basename + ' or path equals ' + dstFile)
return True
else:
print(" images is not compressed which named " + basename + ' or path equals ' + dstFile)
return False
##########################################
# @function 向压缩信息表单插入记录
# @description 如果图片信息存在于数据库中,则表明图片被压缩过,不需要再次压缩
##########################################
def insertTableCompressLog(basename , filename , dstFile , dsize , osize):
#进行建表语句
createTableCompressLog()
#没有数据则插入数据
if not selectTableCompressLog(basename , dstFile):
#插入数据:
cu.execute("insert into compresslog values('" + basename + "', '" + filename + "' , '" + dstFile + "' , " + str(dsize) + " , " + str(osize) + " , 0)")
#提交数据
cu.commit()
##########################################
# @function 图片压缩操作
# @param srcFile 待压缩图片
##########################################
def compressImage(srcPath,dstPath):
for filename in os.listdir(srcPath):
#如果不存在目的目录则创建一个,保持层级结构
if not os.path.exists(dstPath):
os.makedirs(dstPath)
#拼接完整的文件或文件夹路径
srcFile=os.path.join(srcPath,filename)
dstFile=os.path.join(dstPath,filename)
srcFiledirName = os.path.dirname(srcFile)
basename = os.path.basename(srcFile) #获得文件全称 例如 migo.png
filename, fileSuffix = os.path.splitext(basename) #获得文件名称和后缀名 例如 migo 和 png
#如果是文件就处理
if os.path.isfile(srcFile) and picIsCorrect(fileSuffix) and picIsBig(srcFile) and (not picIsCompressed(basename , dstFile)):
#打开原图片缩小后保存,可以用if srcFile.endswith(".jpg")或者split,splitext等函数等针对特定文件压缩
sImg=Image.open(srcFile).convert('RGB')
#获取原图片长宽
w,h=sImg.size
#获取压缩前图片大小,单位KB
osize = os.path.getsize(srcFile)/1024
if osize > 4096 :
width = w/(compressRatio + 0.25)
height = h/(compressRatio + 0.25)
dImg=sImg.resize((int(width),int(height)),Image.ANTIALIAS)
elif osize > 2048 :
width = w/(compressRatio + 0.2)
height = h/(compressRatio + 0.2)
dImg=sImg.resize((int(width),int(height)),Image.ANTIALIAS)
elif osize > 1024 :
width = w/(compressRatio + 0.1)
height = h/(compressRatio + 0.1)
dImg=sImg.resize((int(width),int(height)),Image.ANTIALIAS)
else:
width = w/(compressRatio + 0.05)
height = h/(compressRatio + 0.05)
dImg=sImg.resize((int(w/width),int(h/height)),Image.ANTIALIAS)
#保存压缩后文件,单位KB
dImg.save(dstFile)
#获取压缩后文件大小
dsize = os.path.getsize(dstFile)/1024
#如果压缩后,压缩图片大于原图片,则在用原图片覆盖被压缩的图片
if(dsize > osize):
sImg.save(dstFile)
dsize = os.path.getsize(dstFile)/1024
#插入数据,被压缩的图片信息记录到数据库中,下次不再压缩
insertTableCompressLog(basename , filename , dstFile , dsize , osize)
logging.info("srcFile: " + srcFile + " dstFile: " + dstFile)
logging.info("filename: " + filename + " fileSuffix: " + fileSuffix)
logging.info("originally size:" + str(osize))
logging.info("compressed size:" + str(dsize) + " " + dstFile + " compressed succeeded" )
print("srcFile: " + srcFile + " dstFile: " + dstFile + "filename: " + filename + " fileSuffix: " + fileSuffix + "originally size:" + str(osize) + "compressed size:" + str(dsize) + " " + dstFile + " compressed succeeded" )
#如果是文件夹就递归
if os.path.isdir(srcFile):
compressImage(srcFile,dstFile)
##########################################
# @function 主函数执行区域
# @description 快速压缩图片
##########################################
if __name__=='__main__':
#压缩比率
compressRatio = 1.1
#是否建表标识
createTableFlag = True
#Create Connection to INSERT COMPRESS IMAGES INFO TO DATABASE
cx = sqlite3.connect("./database.db")
#获取游标
cu = cx.cursor()
#设置打印日志格式
logging.basicConfig(filename='compress.log', level=logging.INFO)
#进行递归压缩
compressImage('/path/need compress dir/', '/path/save compress dir/')
将上述文本保存为compress.py,修改上述文件中,需要压缩的目录,和需要存放被压缩的目录
执行命令
chmod +x compress.py
python ./compress.py
说明事项
(1) 修改低于多少KB的文件不被压缩
##########################################
# @function 判断图片大小是否需要压缩
# @param srcFile 待压缩图片
##########################################
def picIsBig(srcFile):
size = os.path.getsize(srcFile)/1024
if size > 0 :
return True
else:
return False
修改 size 判断大小,目前默认为0
(2) 设置被存放在数据库中的图片记录将不被压缩,已经压缩的图片信息将被存放在数据库中
##########################################
# @function 判断图片大小是否被压缩过
# @description 如果图片信息存在于数据库中,则表明图片被压缩过,不需要再次压缩
# @param basename 待压缩图片名称
##########################################
def picIsCompressed(basename , dstFile):
if selectTableCompressLog(basename , dstFile):
#print(" images is already compressed which named " + basename + ' or path equals ' + dstFile)
return True
else:
return False
如果被压缩过的图片,也需要再次压缩,请将return True改为return False