图片压缩工具

[复制链接]
136 |11
发表于 2025-11-3 02:14:20 | 显示全部楼层 |阅读模式
  在为网站上传图片时,经常会遇到对图片文件大小和分辨率的限制。为了确保图片符合这些要求而不失质量,图片压缩工具成为不可或缺的好帮手。这类工具不仅能够有效减小文件体积,还能保持图像的清晰度,确保网页加载速度不受影响。
主要功能与优势:
  1.智能压缩:利用先进的算法,在几乎不影响视觉效果的情况下减少图片文件的大小,确保图片符合网站的上传要求

  2.格式转换:部分工具还提供格式转换功能,可以将图片转换为最适合网络使用的格式(如 JPEG、PNG 等多种图片格式),进一步优化文件大小。

  3.自定义设置:允许用户调整压缩级别,根据具体需求平衡图片质量和文件大小。

  4.即时预览:一些工具提供即时预览功能,让用户可以在压缩前后对比图片质量,确保最终效果满意。

操作步骤截图



  软件下载地址:https://wwtg.lanzouo.com/isxNl2isztqj    密码:52pj

   代码源码如下,有需要的可以自行修改研究:
[Python]  
  1. import os
  2. import re
  3. import tkinter as tk
  4. from tkinter import filedialog, messagebox, ttk
  5. from PIL import Image, ImageTk, UnidentifiedImageError
  6. import threading
  7. import logging
  8. # 设置日志配置
  9. logging.basicConfig(level=logging.DEBUG, format='%(asctime)s - %(levelname)s - %(message)s')
  10. class ImageCompressorApp:
  11.     def __init__(self, root):
  12.         self.root = root
  13.         self.root.title("图片压缩工具 by ke")
  14.         self.root.geometry("1024x650")
  15.         self.root.configure(bg="#f0f0f0")
  16.         # 初始化变量
  17.         self.image_path = None  # 图片路径
  18.         self.output_location = None  # 输出位置
  19.         self.target_size_kb = tk.IntVar(value=400)  # 默认目标大小为400KB
  20.         self.new_filename = tk.StringVar()  # 新文件名
  21.         self.output_format = tk.StringVar(value="JPG")  # 修改默认输出格式为JPG
  22.         # 创建界面元素
  23.         self.create_widgets()
  24.     def create_widgets(self):
  25.         main_frame = tk.Frame(self.root, bg="#f0f0f0")
  26.         main_frame.pack(expand=True, fill='both', padx=20, pady=20)
  27.         # 文件选择和预览
  28.         img_frame = tk.Frame(main_frame, bg="#f0f0f0")
  29.         img_frame.pack(fill='x')
  30.         self.img_label = tk.Label(img_frame, text="请加载一张图片", bg="#f0f0f0")
  31.         self.img_label.pack(side=tk.LEFT, padx=10, pady=10)
  32.         browse_button = tk.Button(img_frame, text="选择图片...", command=self.browse_files)
  33.         browse_button.pack(side=tk.RIGHT, padx=10, pady=10)
  34.         # 目标大小输入框
  35.         size_frame = tk.Frame(main_frame, bg="#f0f0f0")
  36.         size_frame.pack(fill='x', pady=5)
  37.         tk.Label(size_frame, text="目标大小 (KB):", bg="#f0f0f0").pack(side=tk.LEFT, padx=5)
  38.         self.size_entry = tk.Entry(size_frame, textvariable=self.target_size_kb, width=10)
  39.         self.size_entry.pack(side=tk.LEFT, padx=5)
  40.         # 设置新文件名
  41.         filename_frame = tk.Frame(main_frame, bg="#f0f0f0")
  42.         filename_frame.pack(fill='x', pady=5)
  43.         tk.Label(filename_frame, text="新文件名:", bg="#f0f0f0").pack(side=tk.LEFT, padx=5)
  44.         tk.Entry(filename_frame, textvariable=self.new_filename, width=30).pack(side=tk.LEFT, padx=5)
  45.         # 选择输出格式
  46.         format_frame = tk.Frame(main_frame, bg="#f0f0f0")
  47.         format_frame.pack(fill='x', pady=5)
  48.         tk.Label(format_frame, text="输出格式:", bg="#f0f0f0").pack(side=tk.LEFT, padx=5)
  49.         format_combobox = ttk.Combobox(format_frame, textvariable=self.output_format,
  50.                                        values=["JPG", "JPEG", "PNG", "BMP", "GIF"], width=10)
  51.         format_combobox.current(0)  # 设置默认选中项为第一个选项,即"JPG"
  52.         format_combobox.pack(side=tk.LEFT, padx=5)
  53.         # 输出位置选择
  54.         output_frame = tk.Frame(main_frame, bg="#f0f0f0")
  55.         output_frame.pack(fill='x', pady=5)
  56.         tk.Label(output_frame, text="输出位置:", bg="#f0f0f0").pack(side=tk.LEFT, padx=5)
  57.         self.output_location_var = tk.StringVar()
  58.         tk.Entry(output_frame, textvariable=self.output_location_var, width=50).pack(side=tk.LEFT, padx=5)
  59.         tk.Button(output_frame, text="选择...", command=self.select_output_location).pack(side=tk.LEFT, padx=5)
  60.         # 创建一个容器用于放置压缩并保存按钮和进度条
  61.         bottom_frame = tk.Frame(self.root, bg="#f0f0f0")
  62.         bottom_frame.pack(side=tk.BOTTOM, fill='x', pady=20)
  63.         # 压缩并保存按钮
  64.         compress_button = tk.Button(bottom_frame, text="压缩并保存", command=self.start_compress_and_save)
  65.         compress_button.pack(side=tk.LEFT, padx=10)
  66.         # 进度条放在最下方
  67.         self.progress = ttk.Progressbar(bottom_frame, orient="horizontal", length=700, mode="determinate")
  68.         self.progress.pack(side=tk.RIGHT, padx=10)
  69.     def load_image(self, path):
  70.         """加载并显示图片预览"""
  71.         try:
  72.             self.image_path = path
  73.             img = Image.open(path)
  74.             img.thumbnail((300, 300))
  75.             self.photo = ImageTk.PhotoImage(img)
  76.             self.img_label.config(image=self.photo)
  77.         except Exception as e:
  78.             logging.error(f"加载图片时出错: {str(e)}")
  79.             self.show_message("错误", f"加载图片时出错: {str(e)}")
  80.     def browse_files(self):
  81.         """打开文件对话框选择图片"""
  82.         filename = filedialog.askopenfilename(
  83.             title="选择图片",
  84.             filetypes=[("Image files", "*.png *.jpg *.jpeg *.bmp *.gif")]
  85.         )
  86.         if filename:
  87.             self.load_image(filename)
  88.     def select_output_location(self):
  89.         """选择图片压缩后的输出位置"""
  90.         directory = filedialog.askdirectory(title="选择输出位置")
  91.         if directory:
  92.             self.output_location_var.set(directory)
  93.     def start_compress_and_save(self):
  94.         """启动压缩线程并在UI上显示进度条"""
  95.         self.progress["value"] = 0  # 初始化进度条为0%
  96.         self.progress["maximum"] = 100  # 设置进度条的最大值为100%
  97.         compress_thread = threading.Thread(target=self.compress_and_save)
  98.         compress_thread.start()
  99.     def compress_and_save(self):
  100.         """执行图片压缩并保存到指定位置"""
  101.         try:
  102.             if not self.image_path or not self.output_location_var.get():
  103.                 self.show_message("警告", "请选择图片和输出位置!")
  104.                 return
  105.             new_filename = sanitize_filename(self.new_filename.get().strip())
  106.             if not new_filename:
  107.                 self.show_message("警告", "请输入有效的文件名!")
  108.                 return
  109.             output_filename = f"{new_filename}.{self.get_output_extension()}"
  110.             output_path = os.path.join(self.output_location_var.get(), output_filename)
  111.             # 检查输出路径有效性
  112.             if not os.path.isdir(self.output_location_var.get()):
  113.                 logging.error(f"输出位置不存在: {self.output_location_var.get()}")
  114.                 self.show_message("错误", "选择的输出位置无效,请重新选择。")
  115.                 return
  116.             # 检查是否有写权限
  117.             if not os.access(self.output_location_var.get(), os.W_OK):
  118.                 logging.error(f"没有写入权限: {self.output_location_var.get()}")
  119.                 self.show_message("错误", "没有足够的权限在选择的位置写入文件。")
  120.                 return
  121.             target_size_kb = self.target_size_kb.get()
  122.             original_size_kb = os.path.getsize(self.image_path) / 1024
  123.             if original_size_kb  target_size_kb and quality >= 10:
  124.                 try:
  125.                     img.save(output_path, format=format_name, optimize=True, quality=quality)
  126.                     original_size_kb = os.path.getsize(output_path) / 1024
  127.                     quality -= 5
  128.                     self.update_progress(quality)
  129.                 except IOError as e:
  130.                     logging.error(f"IO 错误: {str(e)}")
  131.                     raise ValueError(f"IO 错误: {str(e)}")
  132.                 except Exception as e:
  133.                     logging.error(f"保存图片时出错: {str(e)}")
  134.                     raise ValueError(f"保存图片时出错: {str(e)}")
  135.             if original_size_kb > target_size_kb:
  136.                 raise ValueError("无法将图片压缩到指定大小!请尝试增加目标大小或减少图片复杂度。")
  137.         except UnidentifiedImageError:
  138.             logging.error("无法识别的图片格式")
  139.             self.show_message("错误", "无法识别的图片格式,请选择其他图片。")
  140.         except Exception as e:
  141.             logging.error(f"压缩图片时出错: {str(e)}")
  142.             self.show_message("错误", f"压缩图片时出错: {str(e)}")
  143.     def get_output_extension(self):
  144.         """根据输出格式返回正确的文件扩展名"""
  145.         format_name = self.output_format.get().upper()
  146.         if format_name in ["JPG", "JPEG"]:
  147.             return "jpg"
  148.         elif format_name == "PNG":
  149.             return "png"
  150.         elif format_name == "BMP":
  151.             return "bmp"
  152.         elif format_name == "GIF":
  153.             return "gif"
  154.         else:
  155.             return "jpg"
  156.     def get_output_format(self):
  157.         """根据输出格式返回正确的Pillow格式名称"""
  158.         format_name = self.output_format.get().upper()
  159.         if format_name in ["JPG", "JPEG"]:
  160.             return "JPEG"
  161.         elif format_name == "PNG":
  162.             return "PNG"
  163.         elif format_name == "BMP":
  164.             return "BMP"
  165.         elif format_name == "GIF":
  166.             return "GIF"
  167.         else:
  168.             return "JPEG"
  169.     def update_progress(self, quality):
  170.         """更新进度条的值"""
  171.         max_quality = 95
  172.         min_quality = 10
  173.         progress_value = ((max_quality - quality) / (max_quality - min_quality)) * 100
  174.         self.root.after(0, lambda: self.set_progress_value(min(progress_value, 100)))
  175.     def set_progress_value(self, value):
  176.         """设置进度条的值"""
  177.         self.progress["value"] = value
  178.     def show_message(self, title, message):
  179.         """显示消息框并停止进度条"""
  180.         self.root.after(0, lambda: messagebox.showinfo(title, message))
  181. def sanitize_filename(filename):
  182.     """清理文件名中的非法字符"""
  183.     return re.sub(r'[\\/*?:"|]', "", filename)
  184. if __name__ == "__main__":
  185.     root = tk.Tk()
  186.     app = ImageCompressorApp(root)
  187.     root.mainloop()
复制代码

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

发表于 2025-11-3 02:14:54 | 显示全部楼层
我刚才对代码做了修改,支持打开软件后自动加载当前目录,也可以选择其它文件夹,并对选择的目录下的所有文件批量压缩保存,对保存的文件名进行自定义,输出目录默认为当前文件夹,也可以自定义。

就是说打开软件后,只需要设置需要的大小,点击开始,就可以对当前文件夹下的所有图片进行批量处理。

是PY3.11环境下做的,不支持WIN7

下载地址为:
本来是想上传一个图片的,但是这个图片上传好像是要先上传某个空间,就先不上传图片了。想下载的自己下载吧。

https://xxkk.lanzoub.com/izyxk2jneked
回复

使用道具 举报

发表于 2025-11-3 02:15:01 | 显示全部楼层
1.谢邀,楼主还在学习python,要是改好了 我又继续发布。
2.目前版本只支持单个压缩。
3.网站一般上传的是点毕业证,学位证还有奖状之类的。
回复

使用道具 举报

发表于 2025-11-3 02:15:36 | 显示全部楼层
没批量啊
回复

使用道具 举报

发表于 2025-11-3 02:16:23 | 显示全部楼层
好东西,试了一下,很好用。
回复

使用道具 举报

发表于 2025-11-3 02:16:44 | 显示全部楼层
这个能批量压缩吗 ?  楼主
回复

使用道具 举报

发表于 2025-11-3 02:17:42 | 显示全部楼层
好东西啊 支持支持!
回复

使用道具 举报

发表于 2025-11-3 02:17:59 | 显示全部楼层
感谢楼主!
回复

使用道具 举报

发表于 2025-11-3 02:18:45 | 显示全部楼层
1.谢邀,楼主还在学习python,要是改好了 我又继续发布。
2.目前版本只支持单个压缩。
3.网站一般上传的是点毕业证,学位证还有奖状之类的。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

发表于 2025-11-3 02:19:41 | 显示全部楼层
哈哈 感谢支持,

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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