吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 1977|回复: 28
收起左侧

[Python 原创] tkinter批量压缩图片

  [复制链接]
Eks6666 发表于 2023-8-6 00:52
[Python] 纯文本查看 复制代码
import tkinter as tk
from tkinter import ttk
from tkinter import filedialog
import tkinter.messagebox
from tkinter import scrolledtext#滚动文本框组件
from tkinter import Menu
from tkinter import ttk
import time
import re
import os
import os.path as osp
from PIL import Image#处理图片库

class MyApp(tk.Tk):
    def __init__(self):
        super().__init__()
        self.title("My App")
        self.geometry("1080x680+390+190")
        #self.resizable(0, 0)
        # 创建一个欢迎Label
        tk.Label(self, text='`欢迎进入百胜通信工程有限公司工作系统`', font=("楷体", 15)).pack(padx=20, pady=5)
        # 添加分隔线
        ttk.Separator(self, orient="horizontal").pack(fill="x")
        ttk.Separator(self, orient="horizontal").pack(fill="x")        
        # 创建Notebook小部件
        self.notebook = ttk.Notebook(self)
        self.notebook.pack(fill="both", expand=True)
                
        # 创建页面列表,定义了一个名为pages的元组列表,其中每个元组包含页面的名称和实现页面的类
        pages = [
            ("主页面", StartPage),
            ("子系统2", Page2),

        
        ]
        # 使用循环创建页面
        for name, cls in pages:
            page = cls(self.notebook)
            self.notebook.add(page, text=name)
        
        # 修改选项卡文字字体
        style = ttk.Style()
        style.configure("TNotebook.Tab", font=("楷体", 10), foreground="red")


# 创建了一个名为Page的基类
class Page(ttk.Frame):
    def __init__(self, parent, name):
        super().__init__(parent)
        self.name = name
        # 添加分隔线
        ttk.Separator(self, orient="horizontal").pack(fill='x')
        ttk.Separator(self, orient="horizontal").pack(fill='x')
        # 创建一个Frame框架
        self.frame = tk.Frame(self, width=800, height=850, highlightbackground="black", highlightthickness=1, bd=3)
        self.frame.pack(side='left', fill='y', padx=135, pady=10)  # side设置left从左至右排列,fill设置y垂直方向填充空白方式
        #添加到父容器中
        self.pack(fill=tk.BOTH, expand=True)  # self.master.pack()就会卡死
# 创建从Page基类派生出每个页面的子类。每个子类都包含该页面的所有小部件和方法
class StartPage(Page):
    def __init__(self, parent):
        super().__init__(parent, "Start_Page")
        tk.Label(self.frame, text="这是主页面").place(relx=0.5, rely=0.0, anchor='n')

class Page2(Page):
    def __init__(self, parent):
        super().__init__(parent, "子系统2")
        self.pic=[]#照片文件夹列表
        self.dic={}#存放文件夹名和文件夹内文件名的键值对
        self.createWidget()
    def createWidget(self):
        tk.Label(self.frame, text="**********照片压缩子系统**********", width=40, height=2, font=("黑体", 15)).place(relx=0.5, rely=0.0, anchor='n')
        tk.Label(self.frame, text="目录路径:", bd=5, width=10, height=2, font=("楷体", 15)).place(x=142, y=100)
        self.lujing = tk.Entry(self.frame, width=25)
        self.lujing.place(x=238, y=116)
        # bind()方法将open_folder()函数与“<Return>”键绑定,以便在用户按下“Enter”键时自动打开所选的文件夹
        #self.lujing.bind("<Return>", self.open_folder)
        tk.Button(self.frame, text="选择", font=("楷体", 11), width=3, height=1,bg='#BFEFFA',
                   command=self.open_folder).place(x=420, y=113)
        tk.Button(self.frame, text="压缩", font=("楷体", 11), width=3, height=1,bg='#BFEFFA',
                   command=self.yasuo).place(x=465, y=113)
        tk.Button(self.frame, text="重置", font=("楷体", 11), width=3, height=1,bg='#BFEFFA',
                   command=self.set_entry).place(x=300, y=480)        
        tk.Button(self.frame, text="返回主页面", font=("楷体", 11), width=10, height=1, command=self.return_to_start)\
        .place(x=350, y=480)#返回主页面
             
        self.texts = tk.Text(self.frame, font=('FangSong', 12), width=63, height=20)
        self.texts.place(x=150, y=142)  # 如果这行代码不单独写,下面代码就会报错'NoneType' object has no attribute 'insert'
        #添加垂直滚动条
        scrollbar = ttk.Scrollbar(self.frame,command=self.texts.yview)
        scrollbar.place(x=639, y=145, height=318)
        self.texts.config(yscrollcommand=scrollbar.set)
        self.texts.insert(tk.END, '已压缩的照片:\n')
        
    def yasuo(self):
        reg1=re.compile(r'\.(jpg|png)$')
        reg2=re.compile(r'(?<=IMG_)\d+_\d+(?=.jpg)')#匹配\d+_\d+
        folder_path = self.lujing.get()  # 获取已经选择的文件夹路径
        if not all([folder_path]):
            tkinter.messagebox.showerror("无法压缩!", "请填写文件夹路径")
           #获取图片的文件名,并拼接完整路径            `
            self.pic.extend(list_j)

        for i in range(len(self.pic)):
            name,exc=osp.split(self.pic[i])#osp.splitext()返回一个文件路径,和文件后缀组成的元组,所以name是一个文件路径。而os.path.split():返回一个路径的目录名和文件名(带后缀)
            nam=osp.basename(name)
            self.dic[nam]=[osp.join(name,exc) for exc in os.listdir(name) if osp.isfile(osp.join(name,exc))
                                                                   if reg1.findall(exc)]#字典的键是唯一的,dic[nam]所以会自动去重
        #print(self.dic)
        #可以利用字典构造DataFrane                                                           
        #df=pd.DataFrame.from_dict(data=dic,orient="columns")
        #进度条
        progress = ttk.Progressbar(self.frame,orient="horizontal",length=155, mode="determinate")
        progress.place(x=500, y=113)
        progress["maximum"] = len(self.pic)#进度条最大值
        progress["value"] = 0#进度条当前值 
        for key,item in self.dic.items():
            #print(f"开始压缩:{key}文件夹内的照片..")
            self.texts.insert(tk.END,f"{key}文件夹内的照片..\n")            
            for file in item:
                im = Image.open(file)#打开里面的jpg文件
                (x,y) = im.size #读取图片尺寸(像素)
                x_s = 2000 #定义缩小后的标准宽度 
                y_s = int(y * x_s / x) #基于标准宽度计算缩小后的高度
                out = im.resize((x_s,y_s),Image.Resampling.LANCZOS) #改变尺寸,保持图片高品质
                out.save(file)#原路径保存
                progress.step(1)
                progress.update()  # 手动更新进度条,没有此代码进度条不显示  
                na,ex=osp.split(file)
                #print(f'{ex}-压缩完成') 
                self.texts.insert(tk.END,f'{ex}-压缩完成\n')
            #print()
            self.texts.insert(tk.END, "\n")#空行
        self.texts.insert(tk.END, f"本次系统共压缩了{len(self.dic)}个照片文件夹"+f'共{len(self.pic)}张照片\n')    
        progress.destroy()#销毁进度条
        tkinter.messagebox.showinfo("压缩完成", f"本次系统共压缩了{len(self.dic)}个照片文件夹"+f',共{len(self.pic)}张照片\n')


    def return_to_start(self):#返回主页面函数
        self.master.master.notebook.select(0)
    def open_folder(self, event=None):
        folder_path = self.lujing.get()  # 取文本框的值,获取目前Entry的字符串内容
        self.folder_path = folder_path
        self.folder_dialog = filedialog.askdirectory(initialdir=folder_path, title='选择')  # 对话框
        # self.lujing.delete(0, tk.END)  # 清空Entry控件中的内容
        self.lujing.insert(0, self.folder_dialog)  # 将选择的文件夹路径更新到Entry控件中
    def set_entry(self):
        self.lujing.delete(0, tk.END)
        self.texts.delete('1.0', tk.END)  # 清空Text文本框内容
        self.pic=[]#清空照片文件夹列表
        self.dic={}#清空存放文件夹名和文件夹内文件名的键值对字典


        

if __name__ == "__main__":
    app = MyApp()
    app.mainloop()
1691254103688.jpg

界面图

界面图

免费评分

参与人数 4吾爱币 +10 热心值 +4 收起 理由
苏紫方璇 + 7 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
shiyezhiping + 1 + 1 谢谢@Thanks!
lccccccc + 1 + 1 感谢大佬分享!
深爱我的女孩 + 1 + 1 谢谢@Thanks!

查看全部评分

本帖被以下淘专辑推荐:

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

Biggaoshou 发表于 2023-8-6 01:53
本帖最后由 Biggaoshou 于 2023-8-6 01:54 编辑

这个脚本有点问题`self.pic`没有赋值,yasuo函数里面len(self.pic)的值是0的,不会进入循环,需要在98行`folder_path = self.lujing.get()  # 获取已经选择的文件夹路径`下面添加以下代码才能复制给self.pic:
[Python] 纯文本查看 复制代码
pics = os.listdir(folder_path)
 # 添加路径
 prefix = folder_path
 self.pic = [os.path.join(prefix,str(x)) for x in pics]


有个问题就是有的图片大小还变大了。
运行结果:
截图_2023-08-06_01-51-20.png
smile1110 发表于 2023-11-1 21:32
遍历文件夹中的所有图片文件,筛选出jpg和png格式的图片;
使用PIL库中的Image模块打开每个图片文件,获取其尺寸(像素);
定义一个缩小后的标准宽度(例如2000像素),根据原始图片的宽高比计算缩小后的高度;
vethenc 发表于 2023-8-6 01:07
深爱我的女孩 发表于 2023-8-6 07:14
手机里面的照片集合到电脑,然后用这个软件,这不是刚刚好吗!
ztqddj007 发表于 2023-8-6 07:53

好好学习 天天向上
bayunwuhui1233 发表于 2023-8-6 08:24
谢谢大佬分享
Elevenbobo 发表于 2023-8-6 08:29
谢谢分享
ITtongxue 发表于 2023-8-6 08:31
不错不错 谢谢分享
fdczsy8 发表于 2023-8-6 08:36
感谢大佬分享
leetauy 发表于 2023-8-6 08:40
压缩的同时能添加时间水印不?
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-24 20:46

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表