python实现一键批量压缩图片-含源码

概要

在开发电商平台时,经常需要展示大量的商品图片,一般设计给出来的图片都比较大,如果原图上传,会导致客户端卡顿,加载速度特别慢,特别是在低端手机中尤为明显,这时我们需要对商品列表图做压缩处理,以达到一个加载性能和客户体验平衡的效果。但是如何才能批量快速压缩图片呢?网上的工具很多都收费,不如自己手写一个。

效果展示

页面效果展示

图片压缩工具实现效果如下图所示,选择原图片文件夹和压缩后存放的目标文件夹,调整图片质量和最终压缩大小点击一键压缩即可实现批量压缩。
在这里插入图片描述

一键压缩效果展示

在这里插入图片描述

实现源码

这里我们使用PIL库做图片处理,PyQt5实现简单的ui页面。

from PIL import Image
import sys
import os
from PyQt5.QtWidgets import QApplication, QWidget, QPushButton,QFileDialog,QSlider,QRadioButton,QHBoxLayout,QMessageBox
from PyQt5.Qt import QTextEdit,Qt
from PyQt5.Qt import QLabel
class App(QWidget):
    def __init__(self):
        super().__init__()
        self.outfile = 'C:\out'  # 输出
        self.path = r"C:\in"  # 输入
        self.title = 'img tool'
        self.left = 100
        self.top = 100
        self.width = 900
        self.height = 800
        self.quality = 90
        self.kb = 90
        self.initUI()

    def get_size(self,file):
        # 获取文件大小:KB
        size = os.path.getsize(file)
        return size / 1024
    def get_outfile(self,infile, outfile):
        if outfile:
            return outfile
        dir, suffix = os.path.splitext(infile)
        outfile = '{}-out{}'.format(dir, suffix)
        return outfile
    def compress_image(self,infile,outfile, mb=500, step=5, quality=100):

        o_size = self.get_size(infile)
        if o_size <= mb:
            return infile
        outfile = self.get_outfile(infile, outfile)
        while o_size > mb:
            im = Image.open(infile)
            try:
                im.save(outfile, quality=quality)
            except Exception as e:
                txt = self.textboxLog.toPlainText() +"\n"+infile +  "压缩失败"
                self.textboxLog.setText(txt)
                return 0,0
            if quality - step < 0:
                break
            quality -= step
            o_size = self.get_size(outfile)
        return outfile, self.get_size(outfile)
    def resize_image(self,infile,outfile,  x_s=350):

        im = Image.open(infile)
        x, y = im.size
        y_s = int(y * x_s / x)
        out = im.resize((int(x_s), y_s), Image.ANTIALIAS)
        outfile = self.get_outfile(infile, outfile)
        out.save(outfile)
    def on_click(self):
        dir = self.textbox21.toPlainText()
        if dir == '':
            self.msg1("请选择图片文件夹")
            return
        dirOut = self.textbox22.toPlainText()
        if dirOut == '':
            self.msg1("请选择图片目标文件夹")
            return
        dirs = os.listdir(dir)
        for i in dirs:
            if i[-4:] == '.jpg' or i[-4:] == '.JPG' or i[-4:] == '.png' or i[-4:] == '.PNG':
                file = dir + '\\' + i
                ofile = dirOut + '\\' + i
                txt =  self.textboxLog.toPlainText() +"\n" + "正在压缩" + i
                self.textboxLog.setText(txt)
                self.compress_image(file, ofile, mb=self.kb,quality=self.quality)  # 120k
                self.resize_image(file,ofile,350)
        txt = self.textboxLog.toPlainText() + "\n#############压缩完毕###################"
        self.textboxLog.setText(txt)
    def Output_File(self):
        directory = QFileDialog.getExistingDirectory(None, "请选择文件夹路径", "D:/")
        self.textbox22.setText(directory)
    def input_File(self):
        directory = QFileDialog.getExistingDirectory(None, "请选择文件夹路径", "D:/")
        self.textbox21.setText(directory)

    def changeZl(self):
        self.quality = self.slider.value()
        self.labelKd.setText("图片质量:" + str(self.quality))
    def changeWidth(self):
        self.width = self.slider.value()
        self.labelKd.setText("宽度(像素):" + str(self.width) + "px")
    def changekb(self):
        self.kb = self.slider2.value()
        self.labelKd2.setText("目标图片大小:" + str(self.kb) + "kb")
    def initUI(self):
        self.setWindowTitle(self.title)
        self.setGeometry(self.left, self.top, self.width, self.height)

        self.lable0 = QLabel("*图片文件夹", self)
        self.lable0.move(10, 8)
        self.textbox21 = QTextEdit(self)
        self.textbox21.move(80, 0)
        self.textbox21.resize(200, 30)
        self.button = QPushButton('选择', self)
        self.button.move(300, 2)
        self.button.clicked.connect(self.input_File)

        self.lable1 = QLabel("*目标文件夹", self)
        self.lable1.move(420, 8)
        self.textbox22 = QTextEdit(self)
        self.textbox22.move(500, 0)
        self.textbox22.resize(200, 30)

        self.button1 = QPushButton('选择', self)
        self.button1.move(700, 2)
        self.button1.clicked.connect(self.Output_File)

        # Create a button in the window
        self.button = QPushButton('一键压缩', self)
        self.button.setStyleSheet("QPushButton {"
                             "background-color: #FF8080;"  # 设置按钮背景颜色为红色
                             "color: rgb(255, 255, 255);"  # 设置按钮文本颜色为白色
                             "}")
        self.button.move(800, 2)

        self.slider = QSlider(Qt.Horizontal,self)
        # 设置滑块的最小值
        self.slider.setMinimum(60)
        # 设置滑块的最大值
        self.slider.setMaximum(100)
        self.slider.setValue(90)
        self.slider.move(20, 50)
        self.slider.resize(300, 30)
        self.slider.setTickInterval(1)
        self.slider.valueChanged.connect(self.changeZl)
        self.labelKd = QLabel("图片质量:90", self)
        self.labelKd.move(330, 50)
        self.labelKd.setStyleSheet("QLabel {"
                                    "color: #ff3030;"  # 设置按钮文本颜色为白色
                                    "}")

        self.slider = QSlider(Qt.Horizontal,self)
        # 设置滑块的最小值
        self.slider.setMinimum(200)
        # 设置滑块的最大值
        self.slider.setMaximum(1000)
        self.slider.setValue(350)
        self.slider.move(20, 100)
        self.slider.resize(300, 30)
        self.slider.setTickInterval(1)
        self.slider.valueChanged.connect(self.changeZl)
        self.labelKd = QLabel("图片质量:90", self)
        self.labelKd.move(330, 50)
        self.labelKd.setStyleSheet("QLabel {"
                                    "color: #ff3030;"  # 设置按钮文本颜色为白色
                                    "}")

        self.slider2 = QSlider(Qt.Horizontal,self)
        # 设置滑块的最小值
        self.slider2.setMinimum(20)
        # 设置滑块的最大值
        self.slider2.setMaximum(500)
        self.slider2.setValue(80)
        self.slider2.move(450, 50)
        self.slider2.resize(300, 30)
        self.slider2.setTickInterval(10)
        self.labelKd2 = QLabel("目标图片大小:90kb", self)
        self.labelKd2.move(750, 50)
        self.labelKd2.setStyleSheet("QLabel {"
                                  "color: #ff3030;"  # 设置按钮文本颜色为白色
                                  "}")
        self.slider2.valueChanged.connect(self.changekb)

        # 信号和槽函数的连接
        # connect button to function on_click
        self.button.clicked.connect(self.on_click)

        self.textboxLog = QTextEdit(self)
        self.textboxLog.move(10, 100)
        self.textboxLog.resize(700, 700)



        self.show()

if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = App()
    app.exit(app.exec_())

小结

上述代码基于python3.8实现,理论上python3以上版本都可运行,直接复制到文件中,保存为py文件即可运行,代码中相关参数可以根据实际情况修改。