前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >教你用Python压缩图片

教你用Python压缩图片

作者头像
py3study
发布2020-01-07 11:59:16
1.4K0
发布2020-01-07 11:59:16
举报
文章被收录于专栏:python3

质量、速度、廉价,选择其中两个

如果需要做图片识别那么必定需要大量的训练素材,我们通常使用爬虫来获取,python爬取bing图片python爬取百度图片,但是怕取下来的图片大小不一,再进行训练之前必须进行裁剪和压缩,今天就来讲一讲图片压缩,下面这个例子是我做一个项目时用到的

代码语言:javascript
复制
import PIL.Image as Image
import os

#图片压缩批处理
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)

        # 如果是文件就处理
        if os.path.isfile(srcFile):
            try:
                #打开原图片缩小后保存,可以用if srcFile.endswith(".jpg")或者split,splitext等函数等针对特定文件压缩
                sImg=Image.open(srcFile)
                w,h=sImg.size
                dImg=sImg.resize((int(w/2),int(h/2)),Image.ANTIALIAS)  #设置压缩尺寸和选项,注意尺寸要用括号
                dImg.save(dstFile) #也可以用srcFile原路径保存,或者更改后缀保存,save这个函数后面可以加压缩编码选项JPEG之类的
                print (dstFile+" 成功!")
            except Exception:
                print(dstFile+"失败!!!!!!!!!!!!!!!!!!!!!!!!!!!!")

        # 如果是文件夹就递归
        if os.path.isdir(srcFile):
            compressImage(srcFile, dstFile)

if __name__=='__main__':
    compressImage("G:/兔屎图片_未处理","G:/兔屎图片_已处理")

可能这个方法不是很通用,因为我当时处理的图片都是很大的,一个图片大概在3M-5M这样,而我并不需要这么高分辨率,因为太高分辨率会影响我机器学习的效率,我就采用最粗暴的方法,使用PIL库中的Image类,调用resize方法把图片的宽高直接砍一半,但是这里我还是采用了Image.ANTIALIAS滤镜虽然这样会使我图片压缩的效率降低一大截,但也尽最大可能的保留了图片的信息。

但我后来又遇到一种更好的压缩图片的方法,使用tinify API进行压缩,通过它压缩的图片信息基本上没有损失,是个压缩图片利它的官方网站:https://tinypng.com/

在它官网上也可以直接进行压缩,不过只能小批量的操作,一次最多20张,下面是使用它进行图片压缩的脚本,你需要自己申请Key填写到程序中

代码语言:javascript
复制
import os
import os.path
import click
import tinify

tinify.key = "你申请的Key,放在这里."
targetFileDirName = "/compress" #输出目录
targetIsDir = False
totalPicCount = 1 #压缩图片总数
compressSuccessPicCount = 0 #图片压缩成功的数量

#这里就是通过tingPng压缩图片的核心代码
def compress_core(file, outputFile):
    source = tinify.from_file(file)  #压缩指定文件
    source.to_file(outputFile)       #将压缩后的文件输出当指定位置

def compress_file(file):
    if not os.path.isfile(file):
        print("你指定的不是文件,不给你压缩这个文件!")
        return
    srcFiledirName = os.path.dirname(file)
    basename = os.path.basename(file)  #获得文件全称 例如  migo.png
    filename, fileSuffix = os.path.splitext(basename)  #获得文件名称和后缀名  例如 migo 和 png
    if picIsCorrect(fileSuffix):
        targetFileDir = srcFiledirName + targetFileDirName
        if not os.path.isdir(targetFileDir):
            os.mkdir(targetFileDir)
        print("正在压缩的图片:  %s"%(srcFiledirName + "/" +basename))
        compress_core(file, targetFileDir + "/" + basename)
        global compressSuccessPicCount
        compressSuccessPicCount += 1
        global targetIsDir
        if targetIsDir is not True:
            print("------------压缩的图片在:  %s  目录下"%(targetFileDir))
    else:
        print("暂不支持压缩 {} 格式的文件, 文件名: {}".format(fileSuffix, basename))

def picIsCorrect(fileSuffix):
    if fileSuffix == ".png" or fileSuffix == ".jpg" or fileSuffix == ".jpeg":
        return True
    else:
        return False

def compress_dir(dir):
    if not os.path.isdir(dir):
        print("你输入的不是一个目录")
        return
    else:
        global targetIsDir
        targetIsDir = True
        srcFilePath = dir #源路径
        for root, dirs, files in os.walk(srcFilePath):
            global totalPicCount
            totalPicCount = len(files)
            for name in files:
                compress_file(srcFilePath + "/" + name)
            break #仅遍历当前目录
    print("------------所有压缩的图片都在: %s  目录下" %(srcFilePath + targetFileDirName))

@click.command()
@click.option('-f', "--file",  type=str,  default=None,  help="单个文件压缩")
@click.option('-d', "--dir",   type=str,  default=None,  help="被压缩的文件夹")
def run(file, dir):
    if not file is None:
        compress_file(file)         #压缩指定的文件
        pass
    elif not dir is None:
        compress_dir(dir)           #压缩指定的目录
        pass
    else:
        compress_dir(os.getcwd())   #压缩当前文件夹
        print("当前目录: %s"%(os.getcwd()))
    print("------压缩结束!------图片总数 ({}),  压缩的图片数量 ({})".format(totalPicCount, compressSuccessPicCount))

if __name__ == "__main__":
    run()
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2019/09/10 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
文件存储
文件存储(Cloud File Storage,CFS)为您提供安全可靠、可扩展的共享文件存储服务。文件存储可与腾讯云服务器、容器服务、批量计算等服务搭配使用,为多个计算节点提供容量和性能可弹性扩展的高性能共享存储。腾讯云文件存储的管理界面简单、易使用,可实现对现有应用的无缝集成;按实际用量付费,为您节约成本,简化 IT 运维工作。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档