专注于为用户提供免费的精品资源,好货不私藏!

图片体积压缩工具源码

admin 软件源码

因为工作需要,需要压缩图片的大小,基本都是小于100K的,就压缩体积,用不着其他的功能,于是就有了这个代码,也可以自定义压缩多大,但是不那么精确,还导入多张图片
图片体积压缩工具源码  图片体积压缩工具源码


 
  1. import tkinter as tk
  2. from tkinter import filedialog, messagebox
  3. from PIL import Image
  4. import os
  5.  
  6. class ImageCompressor:
  7.     def __init__(self, root):
  8.         self.root = root
  9.         self.root.title("图片压缩工具 - 目标大小: 100KB以内")
  10.         self.root.geometry("500x400")
  11.          
  12.         self.target_size = tk.IntVar(value=100)
  13.         self.create_widgets()
  14.  
  15.     def create_widgets(self):
  16.         target_frame = tk.Frame(self.root)
  17.         target_frame.pack(pady=5)
  18.          
  19.         tk.Label(target_frame, text="目标大小 (KB):").pack(side=tk.LEFT)
  20.         self.target_size_entry = tk.Entry(target_frame, width=10, textvariable=self.target_size)
  21.         self.target_size_entry.pack(side=tk.LEFT, padx=5)
  22.          
  23.         tk.Button(target_frame, text="设置", command=self.set_target_size).pack(side=tk.LEFT)
  24.          
  25.         self.select_btn = tk.Button(self.root, text="选择图片", command=self.select_images)
  26.         self.select_btn.pack(pady=10)
  27.         self.file_label = tk.Label(self.root, text="未选择图片", wraplength=400)
  28.         self.file_label.pack(pady=5)
  29.  
  30.         self.compress_btn = tk.Button(self.root, text="开始压缩", command=self.compress_images, state=tk.DISABLED)
  31.         self.compress_btn.pack(pady=10)
  32.  
  33.         self.progress_label = tk.Label(self.root, text="")
  34.         self.progress_label.pack(pady=5)
  35.  
  36.         self.result_text = tk.Text(self.root, height=10, width=60)
  37.         self.result_text.pack(pady=10)
  38.  
  39.         self.clear_btn = tk.Button(self.root, text="清空结果", command=self.clear_results)
  40.         self.clear_btn.pack(pady=5)
  41.  
  42.         self.image_paths = []
  43.      
  44.     def set_target_size(self):
  45.         """设置目标压缩大小"""
  46.         try:
  47.             size = int(self.target_size.get())
  48.             if size <= 0:
  49.                 messagebox.showerror("错误", "目标大小必须大于0KB")
  50.                 return
  51.             if size > 10000:  
  52.                 messagebox.showwarning("警告", "目标大小过大,建议设置一个小于10MB的值")
  53.             
  54.             self.root.title(f"图片压缩工具 - 目标大小: {size}KB以内")
  55.             messagebox.showinfo("成功", f"目标大小已设置为: {size}KB")
  56.         except ValueError:
  57.             messagebox.showerror("错误", "请输入有效的数字")
  58.  
  59.     def select_images(self):
  60.         file_paths = filedialog.askopenfilenames(
  61.             title="选择要压缩的图片",
  62.             filetypes=[
  63.                 ("Image files", "*.jpg *.jpeg *.png *.bmp *.tiff *.webp"),
  64.                 ("All files", "*.*")
  65.             ]
  66.         )
  67.          
  68.         if file_paths:
  69.             self.image_paths = list(file_paths)
  70.             self.file_label.config(text=f"已选择 {len(self.image_paths)} 张图片")
  71.             self.compress_btn.config(state=tk.NORMAL)
  72.             self.result_text.insert(tk.END, f"已选择 {len(self.image_paths)} 张图片 ")
  73.             for path in self.image_paths:
  74.                 self.result_text.insert(tk.END, f"- {path} ")
  75.  
  76.     def compress_images(self):
  77.         if not self.image_paths:
  78.             messagebox.showerror("错误", "请选择至少一张图片")
  79.             return
  80.  
  81.         total_images = len(self.image_paths)
  82.         success_count = 0
  83.          
  84.         for i, image_path in enumerate(self.image_paths):
  85.             try:
  86.                 self.progress_label.config(text=f"正在处理第 {i+1}/{total_images} 张图片...")
  87.                 self.root.update()
  88.                  
  89.                 original_size = os.path.getsize(image_path) / 1024
  90.                 self.result_text.insert(tk.END, f" 处理图片: {os.path.basename(image_path)} ")
  91.                 self.result_text.insert(tk.END, f"原始大小: {original_size:.2f} KB ")
  92.  
  93.                 img = Image.open(image_path)
  94.  
  95.                 if img.mode in ('RGBA', 'LA', 'P'):
  96.                     img = img.convert('RGB')
  97.  
  98.                 output_path = self.generate_output_path_batch(image_path)
  99.  
  100.                 quality = 95
  101.  
  102.                 while True:
  103.                     img.save(output_path, "JPEG", optimize=True, quality=quality)
  104.  
  105.                     compressed_size = os.path.getsize(output_path) / 1024
  106.                      
  107.                     self.progress_label.config(text=f"正在处理: {os.path.basename(image_path)}, 当前质量: {quality}, 大小: {compressed_size:.2f}KB")
  108.                     self.root.update()
  109.  
  110.                     if compressed_size <= self.target_size.get() or quality <= 10:
  111.                         break
  112.  
  113.                     if compressed_size > self.target_size.get() * 1.5:
  114.                         quality -= 15
  115.                     elif compressed_size > self.target_size.get() * 1.2:
  116.                         quality -= 8
  117.                     else:
  118.                         quality -= 5
  119.                      
  120.                     quality = max(quality, 10)
  121.  
  122.                 final_size = os.path.getsize(output_path) / 1024
  123.                 self.result_text.insert(tk.END, f"最终质量: {quality}, 最终大小: {final_size:.2f} KB ")
  124.                  
  125.                 if final_size <= self.target_size.get():
  126.                     self.result_text.insert(tk.END, f"&#9989; 压缩成功! 文件已保存至: {output_path} ")
  127.                     success_count += 1
  128.                 else:
  129.                     self.result_text.insert(tk.END, f"&#9888;&#65039; 无法压缩到{self.target_size.get()}KB以下,最低压缩到: {final_size:.2f} KB ")
  130.                  
  131.                 self.root.update()
  132.                  
  133.             except Exception as e:
  134.                 self.result_text.insert(tk.END, f"&#10060; 压缩失败: {str(e)} ")
  135.                 messagebox.showerror("错误", f"压缩过程中出现错误: {str(e)}")
  136.          
  137.         self.progress_label.config(text="完成!")
  138.         messagebox.showinfo("完成", f"批量压缩完成! 总共处理: {total_images} 张图片 成功压缩: {success_count} 张图片 无法压缩到{self.target_size.get()}KB以下: {total_images - success_count} 张图片")
  139.  
  140.     def generate_output_path_batch(self, input_path):
  141.         """为批量处理生成输出文件路径"""
  142.         base_name, ext = os.path.splitext(input_path)
  143.         counter = 1
  144.         while True:
  145.             output_path = f"{base_name}_compressed_{counter}.jpg"
  146.             if not os.path.exists(output_path):
  147.                 return output_path
  148.             counter += 1
  149.  
  150.     def generate_output_path(self):
  151.         """生成输出文件路径"""
  152.         base_name, ext = os.path.splitext(self.image_path)
  153.         counter = 1
  154.         while True:
  155.             output_path = f"{base_name}_compressed_{counter}.jpg"
  156.             if not os.path.exists(output_path):
  157.                 return output_path
  158.             counter += 1
  159.  
  160.     def clear_results(self):
  161.         self.result_text.delete(1.0, tk.END)
  162.  
  163.     def compress_image(self):
  164.         pass
  165.  
  166. if __name__ == "__main__":
  167.     root = tk.Tk()
  168.     app = ImageCompressor(root)
  169.     root.mainloop()

复制代码

免责声明

本站提供的一切软件、教程和内容信息仅限用于学习和研究目的;不得将上述内容用于商业或者非法用途,否则,一切后果请用户自负。本站信息来自网络收集整理,版权争议与本站无关。您必须在下载后的24个小时之内,从您的电脑或手机中彻底删除上述内容。如果您喜欢该程序和内容,请支持正版,购买注册,得到更好的正版服务。我们非常重视版权问题,如有侵权请邮件与我们联系处理。敬请谅解!

评论列表