当前位置: 首页 > news >正文

【Deep Seek】Python图片压缩小工具死循环异常修复

一、问题描述

通过Deep Seek写Python代码,制作一个图片压缩小工具,结果发现竖图压缩失败,然后一直让它优化,修复这个问题,结果还是一直失败。后面一步步调试才发现,根本不是横图、竖图的问题,而是某些特定场景(图片大小、压缩质量)下会导致死循环,进而导致压缩失败。

二、问题代码及修复

下方while循环的>=会导致某些特定场景下出现死循环,将等号去掉即可。

    def compress_image(self, input_path, output_path, target_size_kb):"""压缩单张图片到目标大小"""# 打开图片img = Image.open(input_path)# 如果是PNG格式,转换为JPG以获得更好的压缩效果if img.format == 'PNG':img = img.convert('RGB')output_path = output_path.rsplit('.', 1)[0] + '.jpg'# 设置初始质量quality = 95min_quality = 10# 转换为字节并检查大小while quality >= min_quality:# 保存为字节数据以检查大小img.save(output_path, quality=quality, optimize=True)# 检查文件大小file_size_kb = os.path.getsize(output_path) / 1024if file_size_kb <= target_size_kb:break# 质量降低步长根据差距动态调整size_ratio = file_size_kb / target_size_kbquality_reduction = max(5, int(quality * (1 - 1 / size_ratio) / 2))quality = max(min_quality, quality - quality_reduction)

三、修复历程

经过上述几个来回,发现问题依然没有解决,于是我就一步步调试代码去了,此时我以为这个问题是一步步“优化”出来的。

【第一个版本】

后面看了一下发现,前面七个版本基本都是类似的处理,估计我是在第四个版本的时候使用了那张竖图,导致压缩失败了,然后以“失败的结论”去修复失败的问题,结果就一直失败。开了深度思考之后,又优化了两个版本,下面是最后一个版本。

【最后一个版本】

给我整笑了

成功了?我图呢 ?_?

此时我已经不想去纠结了……反正第一个版本修改之后能正常使用了

四、正确代码

第一个版本修改之后的代码:

import os
import sys
import tkinter as tk
from tkinter import filedialog, messagebox, ttk
from PIL import Image
import threadingclass ImageCompressorApp:def __init__(self, root):self.root = rootself.root.title("图片压缩工具")self.root.geometry("500x300")self.root.resizable(False, False)# 变量初始化self.input_folder = tk.StringVar()self.output_folder = tk.StringVar()self.target_size = tk.IntVar(value=100)  # 默认100KBself.create_widgets()def create_widgets(self):# 输入文件夹选择tk.Label(self.root, text="输入文件夹:").grid(row=0, column=0, padx=10, pady=10, sticky="w")tk.Entry(self.root, textvariable=self.input_folder, width=40).grid(row=0, column=1, padx=10, pady=10)tk.Button(self.root, text="浏览", command=self.browse_input).grid(row=0, column=2, padx=10, pady=10)# 输出文件夹选择tk.Label(self.root, text="输出文件夹:").grid(row=1, column=0, padx=10, pady=10, sticky="w")tk.Entry(self.root, textvariable=self.output_folder, width=40).grid(row=1, column=1, padx=10, pady=10)tk.Button(self.root, text="浏览", command=self.browse_output).grid(row=1, column=2, padx=10, pady=10)# 目标大小设置tk.Label(self.root, text="目标大小(KB):").grid(row=2, column=0, padx=10, pady=10, sticky="w")tk.Scale(self.root, from_=10, to=1000, orient=tk.HORIZONTAL, variable=self.target_size).grid(row=2, column=1,padx=10, pady=10,sticky="ew")# 压缩按钮self.compress_btn = tk.Button(self.root, text="开始压缩", command=self.start_compression, bg="lightblue")self.compress_btn.grid(row=3, column=1, padx=10, pady=20)# 进度条self.progress = ttk.Progressbar(self.root, orient=tk.HORIZONTAL, length=400, mode='indeterminate')self.progress.grid(row=4, column=0, columnspan=3, padx=10, pady=10)# 状态标签self.status_label = tk.Label(self.root, text="准备就绪", relief=tk.SUNKEN, anchor=tk.W)self.status_label.grid(row=5, column=0, columnspan=3, sticky="ew", padx=10, pady=10)def browse_input(self):folder = filedialog.askdirectory()if folder:self.input_folder.set(folder)def browse_output(self):folder = filedialog.askdirectory()if folder:self.output_folder.set(folder)def start_compression(self):if not self.input_folder.get() or not self.output_folder.get():messagebox.showerror("错误", "请选择输入和输出文件夹")return# 在后台线程中执行压缩,避免界面冻结thread = threading.Thread(target=self.compress_images)thread.daemon = Truethread.start()def compress_images(self):self.compress_btn.config(state=tk.DISABLED)self.progress.start()self.status_label.config(text="正在压缩图片...")input_dir = self.input_folder.get()output_dir = self.output_folder.get()target_size_kb = self.target_size.get()# 支持的图片格式supported_formats = ('.jpg', '.jpeg', '.png', '.bmp', '.tiff', '.webp')try:# 获取所有图片文件image_files = [f for f in os.listdir(input_dir)if f.lower().endswith(supported_formats)]if not image_files:messagebox.showinfo("信息", "未找到支持的图片文件")return# 创建输出目录(如果不存在)if not os.path.exists(output_dir):os.makedirs(output_dir)# 处理每张图片for i, filename in enumerate(image_files):self.status_label.config(text=f"正在处理 {i + 1}/{len(image_files)}: {filename}")self.root.update()input_path = os.path.join(input_dir, filename)output_path = os.path.join(output_dir, filename)# 压缩图片self.compress_image(input_path, output_path, target_size_kb)self.status_label.config(text=f"完成! 已压缩 {len(image_files)} 张图片")messagebox.showinfo("完成", f"图片压缩完成! 共处理 {len(image_files)} 张图片")except Exception as e:messagebox.showerror("错误", f"压缩过程中发生错误: {str(e)}")finally:self.progress.stop()self.compress_btn.config(state=tk.NORMAL)def compress_image(self, input_path, output_path, target_size_kb):"""压缩单张图片到目标大小"""# 打开图片img = Image.open(input_path)# 如果是PNG格式,转换为JPG以获得更好的压缩效果if img.format == 'PNG':img = img.convert('RGB')output_path = output_path.rsplit('.', 1)[0] + '.jpg'# 设置初始质量quality = 95min_quality = 10# 转换为字节并检查大小while quality > min_quality:# 保存为字节数据以检查大小img.save(output_path, quality=quality, optimize=True)# 检查文件大小file_size_kb = os.path.getsize(output_path) / 1024if file_size_kb <= target_size_kb:break# 质量降低步长根据差距动态调整size_ratio = file_size_kb / target_size_kbquality_reduction = max(5, int(quality * (1 - 1 / size_ratio) / 2))quality = max(min_quality, quality - quality_reduction)def main():root = tk.Tk()app = ImageCompressorApp(root)root.mainloop()if __name__ == "__main__":main()

原图998KB,压缩后140KB,压缩格式为jpg,支持批量压缩(压缩所选文件夹下的所有图片)

(P.S. 后续将发布进一步优化的版本)


文章转载自:

http://RKseMn0T.rcntx.cn
http://A13fSSZz.rcntx.cn
http://N2p7l5Yu.rcntx.cn
http://WVxNGyA9.rcntx.cn
http://IivcgAJF.rcntx.cn
http://jg6h0kTZ.rcntx.cn
http://MRwQ9yTW.rcntx.cn
http://3vwtk2xi.rcntx.cn
http://nfdEst9v.rcntx.cn
http://C5yZQuJU.rcntx.cn
http://xTUD1iiJ.rcntx.cn
http://gCx3nfJ3.rcntx.cn
http://DnUgAwpe.rcntx.cn
http://gJHLqoFS.rcntx.cn
http://ex62VL2t.rcntx.cn
http://Tv7iOVDY.rcntx.cn
http://NNvaN6dV.rcntx.cn
http://weZMG3LI.rcntx.cn
http://xOunJO9X.rcntx.cn
http://kHwkhTLU.rcntx.cn
http://tYj3XxFh.rcntx.cn
http://Q4srgD2d.rcntx.cn
http://GUHIGXCw.rcntx.cn
http://AnZrbzbp.rcntx.cn
http://RwXROd73.rcntx.cn
http://p5g44DqR.rcntx.cn
http://Q4OlUcbh.rcntx.cn
http://BgSQCEQN.rcntx.cn
http://VMADJd9N.rcntx.cn
http://ue98vTaL.rcntx.cn
http://www.dtcms.com/a/382361.html

相关文章:

  • 使用 NVIDIA GPU 加速让 XGBoost 快速提升 46 倍
  • NightCafe Generator
  • jenkins脚本触发部署
  • nginx(介绍+源码安装+平滑升级和回滚)
  • 解决 MobaXterm 左侧文件列表(SCP/SFTP)不显示问题
  • Windows 2012 系统如何修改网卡DNS?
  • 压缩和归档
  • 柔和的绿色风格人像自拍照Lr调色教程,,手机滤镜PS+Lightroom预设下载!
  • 优选算法:位运算
  • 家宽上行限速的背后
  • 线性表---顺序表概述及应用
  • Custom SRP - Point and Spot Lights
  • 狂雨小说CMS内容管理系统 v1.5.5 pc+h5自适应网站
  • DeepSeek实战--自定义工具
  • 同位素分离
  • PID算法:从理论到实践的全面解析
  • 0x03-g a+b ib
  • 【Linux】初识Linux
  • Tomcat介绍与核心操作讲解(以Rhel9.3为例)
  • @RequiredArgsConstructor使用
  • 脉冲串函数在数字信号处理中的核心应用与价值
  • AI助力HTML5基础快速入门:从零开始理解网页结构
  • 大数据与财务管理专业如何转型做金融科技?
  • 【开题答辩全过程】以 高校实习信息管理系统为例,包含答辩的问题和答案
  • 贪心算法应用:推荐冷启动问题详解
  • “单标签/多标签” vs “二分类/多分类”
  • 多商户异次元发卡网是啥啊?
  • 使用 Anaconda Distribution 安装 Python + GDAL并在vscode配置开发环境(完整版)
  • 先进电机拓扑及控制算法介绍(3)——以“数据”驱动电机实现真正的无模型
  • 进程卡顿怎么办?Process Lasso 免费功能实测解析