新手代码【1】之图片批量压缩

查看 29|回复 1
作者:7631329   
新手代码【1】之图片压缩,适合新手学些Python
每一步的代码都加上了注释
[Python] 纯文本查看 复制代码# 导入 wxPython 库,用于创建图形用户界面
import wx
# 导入 os 模块,用于进行文件和目录操作
import os
# 从 PIL 库中导入 Image 模块,用于处理图片
from PIL import Image
# 导入 threading 模块,用于实现多线程操作
import threading
# 定义滚动面板类,继承自 wx.ScrolledWindow
class ScrollablePanel(wx.ScrolledWindow):
    # 类的初始化方法
    def __init__(self, parent):
        # 调用父类的初始化方法
        super().__init__(parent)
        # 创建一个垂直的 BoxSizer 用于布局管理
        self.sizer = wx.BoxSizer(wx.VERTICAL)
        # 将该 sizer 设置给当前窗口
        self.SetSizer(self.sizer)
        # 设置滚动的速率
        self.SetScrollRate(5, 5)
# 自定义文件拖拽目标类,继承自 wx.FileDropTarget
class MyFileDropTarget(wx.FileDropTarget):
    # 类的初始化方法
    def __init__(self, window):
        # 调用父类的初始化方法
        wx.FileDropTarget.__init__(self)
        # 保存传入的窗口对象
        self.window = window
    # 当有文件拖拽到目标区域时触发的方法
    def OnDropFiles(self, x, y, filenames):
        # 调用窗口对象的 add_images 方法处理拖拽的文件
        self.window.add_images(filenames)
        return True
# 定义图片压缩应用程序类,继承自 wx.Frame
class ImageCompressorApp(wx.Frame):
    # 类的初始化方法
    def __init__(self):
        # 调用父类的初始化方法,设置窗口标题和大小
        super().__init__(None, title="图片批量压缩工具", size=(1200, 800))
        # 创建主面板
        self.panel = wx.Panel(self)
        # 创建顶部标题标签
        title_label = wx.StaticText(self.panel, label="图片批量压缩工具", style=wx.ALIGN_CENTER,
                                    pos=(0, 10), size=(1200, -1))
        # 设置标题字体
        font = wx.Font(36, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_BOLD)
        title_label.SetFont(font)
        # 创建操作按钮和设置区域的面板
        button_panel = wx.Panel(self.panel)
        # 创建批量选择图片按钮
        select_button = wx.Button(button_panel, label="批量选择图片", size=(200, 30))
        # 创建清理已压缩文件按钮
        clear_button = wx.Button(button_panel, label="清理已压缩文件", size=(200, 30))
        # 创建一个水平的 BoxSizer 用于按钮布局
        button_sizer = wx.BoxSizer(wx.HORIZONTAL)
        # 将选择按钮添加到 sizer 中
        button_sizer.Add(select_button, 0, wx.ALL, 10)
        # 将清理按钮添加到 sizer 中
        button_sizer.Add(clear_button, 0, wx.ALL, 10)
        # 将 sizer 设置给按钮面板
        button_panel.SetSizer(button_sizer)
        # 创建拖拽区域的面板
        self.drop_panel = wx.Panel(self.panel, style=wx.BORDER_SUNKEN)
        # 创建拖拽提示标签
        drop_label = wx.StaticText(self.drop_panel, label="拖拽图片到此处", style=wx.ALIGN_CENTER)
        # 设置拖拽提示标签的字体
        drop_font = wx.Font(24, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_ITALIC, wx.FONTWEIGHT_NORMAL)
        drop_label.SetFont(drop_font)
        # 创建一个垂直的 BoxSizer 用于拖拽区域布局
        drop_sizer = wx.BoxSizer(wx.VERTICAL)
        # 将拖拽提示标签添加到 sizer 中
        drop_sizer.Add(drop_label, 1, wx.EXPAND | wx.ALL, 50)
        # 将 sizer 设置给拖拽面板
        self.drop_panel.SetSizer(drop_sizer)
        # 创建文件拖拽目标实例
        dt = MyFileDropTarget(self)
        # 将拖拽目标设置给拖拽面板
        self.drop_panel.SetDropTarget(dt)
        # 创建滚动区域面板
        self.scroll_panel = ScrollablePanel(self.panel)
        # 初始化图片路径列表
        self.image_paths = []
        # 初始化进度条列表
        self.progress_bars = []
        # 初始化图片信息标签列表
        self.image_labels = []
        # 创建主布局 sizer
        main_sizer = wx.BoxSizer(wx.VERTICAL)
        # 将标题标签添加到主 sizer 中
        main_sizer.Add(title_label, 0, wx.EXPAND | wx.ALL, 10)
        # 将按钮面板添加到主 sizer 中
        main_sizer.Add(button_panel, 0, wx.EXPAND | wx.ALL, 10)
        # 将拖拽面板添加到主 sizer 中
        main_sizer.Add(self.drop_panel, 1, wx.EXPAND | wx.ALL, 20)
        # 将滚动面板添加到主 sizer 中
        main_sizer.Add(self.scroll_panel, 1, wx.EXPAND | wx.ALL, 10)
        # 将主 sizer 设置给主面板
        self.panel.SetSizer(main_sizer)
        # 绑定选择图片按钮的点击事件到 select_images 方法
        select_button.Bind(wx.EVT_BUTTON, self.select_images)
        # 绑定清理已压缩文件按钮的点击事件到 clear_compressed_files 方法
        clear_button.Bind(wx.EVT_BUTTON, self.clear_compressed_files)
    # 处理文件拖拽事件的方法
    def on_drop(self, event):
        # 获取拖拽的文件路径列表
        file_paths = event.GetFiles()
        # 调用 add_images 方法处理文件路径列表
        self.add_images(file_paths)
    # 处理选择图片按钮点击事件的方法
    def select_images(self, event):
        # 创建文件选择对话框
        dlg = wx.FileDialog(self, "选择图片", wildcard="图片文件 (*.png;*.jpg;*.jpeg;*.gif;*.bmp;*.tiff)|*.png;*.jpg;*.jpeg;*.gif;*.bmp;*.tiff",
                            style=wx.FD_OPEN | wx.FD_MULTIPLE)
        # 显示对话框并判断用户是否点击了确定按钮
        if dlg.ShowModal() == wx.ID_OK:
            # 获取用户选择的文件路径列表
            file_paths = dlg.GetPaths()
            # 调用 add_images 方法处理文件路径列表
            self.add_images(file_paths)
        # 销毁对话框
        dlg.Destroy()
    # 添加图片到处理列表的方法
    def add_images(self, file_paths):
        # 遍历文件路径列表
        for path in file_paths:
            # 判断路径是否为文件
            if os.path.isfile(path):
                # 将文件路径添加到图片路径列表中
                self.image_paths.append(path)
                # 获取图片原始大小并转换为 KB
                original_size = os.path.getsize(path) / 1024
                # 获取文件名
                file_name = os.path.basename(path)
                # 生成图片信息标签文本
                label_text = f"{file_name} 原大小:{original_size:.2f}Kb 压缩后大小:未处理 压缩比:未处理"
                # 创建图片信息标签
                file_name_label = wx.StaticText(self.scroll_panel, label=label_text)
                # 设置图片信息标签的字体
                label_font = wx.Font(14, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL)
                file_name_label.SetFont(label_font)
                # 将图片信息标签添加到标签列表中
                self.image_labels.append(file_name_label)
                # 创建进度条
                progress_bar = wx.Gauge(self.scroll_panel, range=100)
                # 将进度条添加到进度条列表中
                self.progress_bars.append(progress_bar)
                # 将图片信息标签添加到滚动面板的 sizer 中
                self.scroll_panel.sizer.Add(file_name_label, 0, wx.ALL, 10)
                # 将进度条添加到滚动面板的 sizer 中
                self.scroll_panel.sizer.Add(progress_bar, 0, wx.ALL | wx.EXPAND, 10)
        # 重新布局滚动面板的 sizer
        self.scroll_panel.sizer.Layout()
        # 设置滚动面板的虚拟大小
        self.scroll_panel.SetVirtualSize(self.scroll_panel.sizer.GetMinSize())
        # 启动一个新线程执行图片压缩操作
        threading.Thread(target=self.start_compression).start()
    # 开始图片压缩的方法
    def start_compression(self):
        # 判断压缩后文件夹是否存在,不存在则创建
        if not os.path.exists("压缩后"):
            os.makedirs("压缩后")
        # 遍历图片路径列表
        for i, path in enumerate(self.image_paths):
            # 调用 compress_image 方法压缩图片
            self.compress_image(path, i)
    # 压缩图片的方法
    def compress_image(self, path, index):
        try:
            # 获取图片原始大小并转换为 KB
            original_size = os.path.getsize(path) / 1024
            # 打开图片
            img = Image.open(path)
            # 获取文件名
            file_name = os.path.basename(path)
            # 生成压缩后图片的输出路径
            output_path = os.path.join("压缩后", file_name)
            # 设置进度条的总步数
            total_steps = 100
            # 模拟进度条更新
            for step in range(total_steps):
                # 调用 wx.CallAfter 在主线程中更新进度条的值
                wx.CallAfter(self.progress_bars[index].SetValue, step + 1)
            # 获取文件扩展名并转换为小写
            file_extension = os.path.splitext(file_name)[1].lower()
            # 生成临时文件路径
            temp_path = os.path.join("压缩后", f"temp_{file_name}")
            # 初始化最佳压缩大小为原始大小
            best_size = original_size
            # 初始化最佳压缩路径为原始路径
            best_path = path
            # 如果文件扩展名是 .png
            if file_extension in ['.png']:
                # 以压缩级别 3 保存图片到临时路径
                img.save(temp_path, compress_level=3)
                # 获取临时文件的大小并转换为 KB
                compressed_size = os.path.getsize(temp_path) / 1024
                # 如果临时文件大小小于最佳大小
                if compressed_size

图片, 路径

四十颗牙   

挺好适合新手
您需要登录后才可以回帖 登录 | 立即注册

返回顶部