吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 4641|回复: 118
上一主题 下一主题
收起左侧

[原创工具] 图片压缩工具

  [复制链接]
跳转到指定楼层
楼主
okeo 发表于 2024-12-23 10:53 回帖奖励
  在为网站上传图片时,经常会遇到对图片文件大小和分辨率的限制。为了确保图片符合这些要求而不失质量,图片压缩工具成为不可或缺的好帮手。这类工具不仅能够有效减小文件体积,还能保持图像的清晰度,确保网页加载速度不受影响。
主要功能与优势:
  1.智能压缩:利用先进的算法,在几乎不影响视觉效果的情况下减少图片文件的大小,确保图片符合网站的上传要求

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

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

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




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

   代码源码如下,有需要的可以自行修改研究:
[Python] 纯文本查看 复制代码
001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051
052
053
054
055
056
057
058
059
060
061
062
063
064
065
066
067
068
069
070
071
072
073
074
075
076
077
078
079
080
081
082
083
084
085
086
087
088
089
090
091
092
093
094
095
096
097
098
099
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
import os
import re
import tkinter as tk
from tkinter import filedialog, messagebox, ttk
from PIL import Image, ImageTk, UnidentifiedImageError
import threading
import logging
 
# 设置日志配置
logging.basicConfig(level=logging.DEBUG, format='%(asctime)s - %(levelname)s - %(message)s')
 
class ImageCompressorApp:
    def __init__(self, root):
        self.root = root
        self.root.title("图片压缩工具 by ke")
        self.root.geometry("1024x650")
        self.root.configure(bg="#f0f0f0")
 
        # 初始化变量
        self.image_path = None  # 图片路径
        self.output_location = None  # 输出位置
        self.target_size_kb = tk.IntVar(value=400# 默认目标大小为400KB
        self.new_filename = tk.StringVar()  # 新文件名
        self.output_format = tk.StringVar(value="JPG"# 修改默认输出格式为JPG
 
        # 创建界面元素
        self.create_widgets()
 
    def create_widgets(self):
        main_frame = tk.Frame(self.root, bg="#f0f0f0")
        main_frame.pack(expand=True, fill='both', padx=20, pady=20)
 
        # 文件选择和预览
        img_frame = tk.Frame(main_frame, bg="#f0f0f0")
        img_frame.pack(fill='x')
 
        self.img_label = tk.Label(img_frame, text="请加载一张图片", bg="#f0f0f0")
        self.img_label.pack(side=tk.LEFT, padx=10, pady=10)
 
        browse_button = tk.Button(img_frame, text="选择图片...", command=self.browse_files)
        browse_button.pack(side=tk.RIGHT, padx=10, pady=10)
 
        # 目标大小输入框
        size_frame = tk.Frame(main_frame, bg="#f0f0f0")
        size_frame.pack(fill='x', pady=5)
        tk.Label(size_frame, text="目标大小 (KB):", bg="#f0f0f0").pack(side=tk.LEFT, padx=5)
        self.size_entry = tk.Entry(size_frame, textvariable=self.target_size_kb, width=10)
        self.size_entry.pack(side=tk.LEFT, padx=5)
 
        # 设置新文件名
        filename_frame = tk.Frame(main_frame, bg="#f0f0f0")
        filename_frame.pack(fill='x', pady=5)
        tk.Label(filename_frame, text="新文件名:", bg="#f0f0f0").pack(side=tk.LEFT, padx=5)
        tk.Entry(filename_frame, textvariable=self.new_filename, width=30).pack(side=tk.LEFT, padx=5)
 
        # 选择输出格式
        format_frame = tk.Frame(main_frame, bg="#f0f0f0")
        format_frame.pack(fill='x', pady=5)
        tk.Label(format_frame, text="输出格式:", bg="#f0f0f0").pack(side=tk.LEFT, padx=5)
        format_combobox = ttk.Combobox(format_frame, textvariable=self.output_format,
                                       values=["JPG", "JPEG", "PNG", "BMP", "GIF"], width=10)
        format_combobox.current(0# 设置默认选中项为第一个选项,即"JPG"
        format_combobox.pack(side=tk.LEFT, padx=5)
 
        # 输出位置选择
        output_frame = tk.Frame(main_frame, bg="#f0f0f0")
        output_frame.pack(fill='x', pady=5)
        tk.Label(output_frame, text="输出位置:", bg="#f0f0f0").pack(side=tk.LEFT, padx=5)
        self.output_location_var = tk.StringVar()
        tk.Entry(output_frame, textvariable=self.output_location_var, width=50).pack(side=tk.LEFT, padx=5)
        tk.Button(output_frame, text="选择...", command=self.select_output_location).pack(side=tk.LEFT, padx=5)
 
        # 创建一个容器用于放置压缩并保存按钮和进度条
        bottom_frame = tk.Frame(self.root, bg="#f0f0f0")
        bottom_frame.pack(side=tk.BOTTOM, fill='x', pady=20)
 
        # 压缩并保存按钮
        compress_button = tk.Button(bottom_frame, text="压缩并保存", command=self.start_compress_and_save)
        compress_button.pack(side=tk.LEFT, padx=10)
 
        # 进度条放在最下方
        self.progress = ttk.Progressbar(bottom_frame, orient="horizontal", length=700, mode="determinate")
        self.progress.pack(side=tk.RIGHT, padx=10)
 
    def load_image(self, path):
        """加载并显示图片预览"""
        try:
            self.image_path = path
            img = Image.open(path)
            img.thumbnail((300, 300))
            self.photo = ImageTk.PhotoImage(img)
            self.img_label.config(image=self.photo)
        except Exception as e:
            logging.error(f"加载图片时出错: {str(e)}")
            self.show_message("错误", f"加载图片时出错: {str(e)}")
 
    def browse_files(self):
        """打开文件对话框选择图片"""
        filename = filedialog.askopenfilename(
            title="选择图片",
            filetypes=[("Image files", "*.png *.jpg *.jpeg *.bmp *.gif")]
        )
        if filename:
            self.load_image(filename)
 
    def select_output_location(self):
        """选择图片压缩后的输出位置"""
        directory = filedialog.askdirectory(title="选择输出位置")
        if directory:
            self.output_location_var.set(directory)
 
    def start_compress_and_save(self):
        """启动压缩线程并在UI上显示进度条"""
        self.progress["value"] = 0  # 初始化进度条为0%
        self.progress["maximum"] = 100  # 设置进度条的最大值为100%
        compress_thread = threading.Thread(target=self.compress_and_save)
        compress_thread.start()
 
    def compress_and_save(self):
        """执行图片压缩并保存到指定位置"""
        try:
            if not self.image_path or not self.output_location_var.get():
                self.show_message("警告", "请选择图片和输出位置!")
                return
 
            new_filename = sanitize_filename(self.new_filename.get().strip())
            if not new_filename:
                self.show_message("警告", "请输入有效的文件名!")
                return
 
            output_filename = f"{new_filename}.{self.get_output_extension()}"
            output_path = os.path.join(self.output_location_var.get(), output_filename)
 
            # 检查输出路径有效性
            if not os.path.isdir(self.output_location_var.get()):
                logging.error(f"输出位置不存在: {self.output_location_var.get()}")
                self.show_message("错误", "选择的输出位置无效,请重新选择。")
                return
 
            # 检查是否有写权限
            if not os.access(self.output_location_var.get(), os.W_OK):
                logging.error(f"没有写入权限: {self.output_location_var.get()}")
                self.show_message("错误", "没有足够的权限在选择的位置写入文件。")
                return
 
            target_size_kb = self.target_size_kb.get()
            original_size_kb = os.path.getsize(self.image_path) / 1024
 
            if original_size_kb <= target_size_kb:
                self.show_message("提示", "原图大小已经小于或等于目标大小,无需压缩。")
                return
 
            self.compress_image(self.image_path, output_path, target_size_kb)
 
            self.set_progress_value(100# 完成后设置进度条为100%
            self.show_message("成功", "图片已成功压缩并保存!")
        except Exception as e:
            logging.error(f"压缩失败: {str(e)}")
            self.show_message("错误", f"压缩失败: {str(e)}")
        finally:
            self.progress.stop()
 
    def compress_image(self, image_path, output_path, target_size_kb):
        """压缩图片至指定大小"""
        try:
            img = Image.open(image_path).convert('RGB'# 确保图片模式兼容
            quality = 95
            original_size_kb = os.path.getsize(image_path) / 1024
            format_name = self.get_output_format()  # 获取正确的格式名称
 
            while original_size_kb > target_size_kb and quality >= 10:
                try:
                    img.save(output_path, format=format_name, optimize=True, quality=quality)
                    original_size_kb = os.path.getsize(output_path) / 1024
                    quality -= 5
                    self.update_progress(quality)
                except IOError as e:
                    logging.error(f"IO 错误: {str(e)}")
                    raise ValueError(f"IO 错误: {str(e)}")
                except Exception as e:
                    logging.error(f"保存图片时出错: {str(e)}")
                    raise ValueError(f"保存图片时出错: {str(e)}")
 
            if original_size_kb > target_size_kb:
                raise ValueError("无法将图片压缩到指定大小!请尝试增加目标大小或减少图片复杂度。")
        except UnidentifiedImageError:
            logging.error("无法识别的图片格式")
            self.show_message("错误", "无法识别的图片格式,请选择其他图片。")
        except Exception as e:
            logging.error(f"压缩图片时出错: {str(e)}")
            self.show_message("错误", f"压缩图片时出错: {str(e)}")
 
    def get_output_extension(self):
        """根据输出格式返回正确的文件扩展名"""
        format_name = self.output_format.get().upper()
        if format_name in ["JPG", "JPEG"]:
            return "jpg"
        elif format_name == "PNG":
            return "png"
        elif format_name == "BMP":
            return "bmp"
        elif format_name == "GIF":
            return "gif"
        else:
            return "jpg"
 
    def get_output_format(self):
        """根据输出格式返回正确的Pillow格式名称"""
        format_name = self.output_format.get().upper()
        if format_name in ["JPG", "JPEG"]:
            return "JPEG"
        elif format_name == "PNG":
            return "PNG"
        elif format_name == "BMP":
            return "BMP"
        elif format_name == "GIF":
            return "GIF"
        else:
            return "JPEG"
 
    def update_progress(self, quality):
        """更新进度条的值"""
        max_quality = 95
        min_quality = 10
        progress_value = ((max_quality - quality) / (max_quality - min_quality)) * 100
        self.root.after(0, lambda: self.set_progress_value(min(progress_value, 100)))
 
    def set_progress_value(self, value):
        """设置进度条的值"""
        self.progress["value"] = value
 
    def show_message(self, title, message):
        """显示消息框并停止进度条"""
        self.root.after(0, lambda: messagebox.showinfo(title, message))
 
def sanitize_filename(filename):
    """清理文件名中的非法字符"""
    return re.sub(r'[\\/*?:"<>|]', "", filename)
 
if __name__ == "__main__":
    root = tk.Tk()
    app = ImageCompressorApp(root)
    root.mainloop()

免费评分

参与人数 16吾爱币 +20 热心值 +14 收起 理由
pw61617393 + 1 + 1 我很赞同!
caihuachaorou87 + 1 + 1 谢谢@Thanks!
http88 + 2 + 1 谢谢@Thanks!
crb8331 + 1 + 1 我很赞同!
lingswell + 1 + 1 我很赞同!
xkjai + 1 我很赞同!
chengkang0535 + 1 用心讨论,共获提升!
xzkr + 1 + 1 谢谢@Thanks!
lgh978 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
jdhnp + 1 + 1 谢谢@Thanks!
laoda1228 + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
墨与非 + 1 + 1 谢谢@Thanks!
alomoi + 1 + 1 我很赞同!
antikou + 1 谢谢@Thanks!
confiant + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
风之暇想 + 7 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!

查看全部评分

本帖被以下淘专辑推荐:

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

推荐
usa118 发表于 2025-1-1 21:27
我刚才对代码做了修改,支持打开软件后自动加载当前目录,也可以选择其它文件夹,并对选择的目录下的所有文件批量压缩保存,对保存的文件名进行自定义,输出目录默认为当前文件夹,也可以自定义。

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

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

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

https://xxkk.lanzoub.com/izyxk2jneked
推荐
 楼主| okeo 发表于 2024-12-24 08:52 |楼主

1.谢邀,楼主还在学习python,要是改好了 我又继续发布。
2.目前版本只支持单个压缩。
3.网站一般上传的是点毕业证,学位证还有奖状之类的。
沙发
妖精的旋律 发表于 2024-12-23 21:18
3#
eonion 发表于 2024-12-24 07:58
好东西,试了一下,很好用。
4#
laoda1228 发表于 2024-12-24 08:05
这个能批量压缩吗 ?  楼主
5#
xlwllm 发表于 2024-12-24 08:33
好东西啊 支持支持!
6#
antikou 发表于 2024-12-24 08:37
感谢楼主!
7#
 楼主| okeo 发表于 2024-12-24 08:41 |楼主
laoda1228 发表于 2024-12-24 08:05
这个能批量压缩吗 ?  楼主

1.谢邀,楼主还在学习python,要是改好了 我又继续发布。
2.目前版本只支持单个压缩。
3.网站一般上传的是点毕业证,学位证还有奖状之类的。

免费评分

参与人数 1吾爱币 +1 热心值 +1 收起 理由
laoda1228 + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!

查看全部评分

8#
 楼主| okeo 发表于 2024-12-24 08:41 |楼主
eonion 发表于 2024-12-24 07:58
好东西,试了一下,很好用。

哈哈 感谢支持,
9#
 楼主| okeo 发表于 2024-12-24 08:42 |楼主

好的呢。
10#
 楼主| okeo 发表于 2024-12-24 08:43 |楼主
petereda 发表于 2024-12-24 08:34
谢谢分享,正需要

好的呢,感谢支持
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

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

GMT+8, 2025-4-9 18:00

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

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