PNG图片批量压缩exe工具+功能纯净+不改变原始尺寸

news2024/11/14 20:27:09

小编最近有一篇png图片要批量压缩,大小都在5MB之上,在网上找了半天要么就是有广告,要么就是有毒,要么就是功能复杂,整的我心烦意乱。

于是我自己用python写了一个纯净工具,只能压缩png图片,没任何广告。在windwos平台上使用。

指定的压缩质量:40

压缩前图片大小

压缩后图片大小

可以看到图片从5MB压缩到了 500KB。指定的质量还是降低,压缩尺寸效果还可以更大。

压缩前和压缩后图片对比

压缩前,大小5.7MB:

压缩后,大小861KB:

使用视频教程

png压缩

代码采用python编写,打包成了exe, 文件目录:

直接运行这个 "批量压缩png图片.exe" 即可。

下载地址:

https://gitee.com/lz-code/soft.git

部分代码展示

import tkinter as tk
from tkinter.filedialog import askdirectory
from tkinter.messagebox import *
import datetime
import _thread
from pathlib import Path
import os


def center_window(root, width, height):
    # 获取屏幕宽高
    screen_width = root.winfo_screenwidth()
    screen_height = root.winfo_screenheight()
    # 计算窗口左上角坐标
    x = (screen_width - width) // 2
    y = (screen_height - height) // 2
    # 设置窗口位置
    root.geometry(f'{width}x{height}+{x}+{y}')


def count_files_with_extension(folder_path, extension1 , extension2):
    count = 0
    path = Path(folder_path)
    # 获取路径下的所有文件并打印文件名称
    for f in path.iterdir():
        if f.is_file():
            full_path = os.path.join(folder_path, f)
            source_name = full_path
            if source_name.endswith(extension1) or source_name.endswith(extension2):
                count += 1

    return count

def open_img_dir(edit):
    path_ = askdirectory()  # 使用askdirectory()方法返回文件夹的路径
    if path_ == "":
        pass
        # showerror('错误', '图片目录未选择')
    else:
        edit.insert(0,path_)


def start_compress(entry_dir,entry_quality):
    img_dir = entry_dir.get()
    img_quality = entry_quality.get()
    if img_dir.strip() == "":
        showerror('错误', '图片目录未选择')
        return
    if img_quality.strip() == "":
        showerror('错误', '压缩质量未设置')
        return
    try:
        img_quality = int(img_quality)
    except:
        showerror('错误', '压缩质量只能是整数')
        return
    if img_quality < 0 or img_quality > 100:
        showerror('错误', '压缩质量在0-100之间')
        return


    def run(img_dir,img_quality):
        try:
            ## 输出路径
            out_dir = img_dir+"/out"
            append_log("创建输入路径:" + out_dir)
            if not os.path.exists(out_dir):
                os.mkdir(out_dir)
            path = Path(img_dir)
            count = 0
            total = count_files_with_extension(img_dir,"png","PNG")
            btn_start.config(text="压缩中 0/"+str(total))
            btn_start.config(state=tk.DISABLED)
            # 获取路径下的所有文件并打印文件名称
            for f in path.iterdir():
                if f.is_file():
                    full_path = os.path.join(img_dir, f)
                    source_name = full_path
       

            append_log("作业压缩完成,存储:" + out_dir)
            btn_start.config(state=tk.NORMAL)
            btn_start.config(text="开始压缩")
            showinfo('提示', '恭喜! 图片压缩完成!')
        except Exception as e:
            import logging
            logging.exception(e)
            append_log(str(e))
            btn_start.config(state=tk.NORMAL)
            btn_start.config(text="开始压缩")

    _thread.start_new_thread(run , (img_dir,img_quality))


def append_log(log):
    current_time = datetime.datetime.now().strftime("%Y-%m-%d-%H:%M:%S")
    log = "["+current_time+"]# " + log + "\n"
    text.insert(tk.END, log + "\n")
    text.see(tk.END)


root = tk.Tk()
root.title("批量PNG压缩 by 【轻量小工具工作室*QQ:3571289092】")
window_width = 500
window_height = 500
center_window(root, window_width, window_height)


uiHeight = 30
padding = 20


hint = tk.Label(root, text="                   ★★★ 无收费,无广告,无毒,自主研发,联系开发可定制 ★★★")
hint.place(x=padding, y=0, width=400, height=uiHeight)


hint2 = tk.Label(root, text="压缩质量")
hint2.place(x=padding, y=uiHeight+padding, width=100, height=uiHeight)

entry_quality=tk.Entry(root,bd=2)
entry_quality.place(x=padding+100, y=uiHeight+padding, width=100, height=uiHeight)
entry_quality.insert(0,40)

hint2 = tk.Label(root, text="0[差]-100[好]")
hint2.place(x=2*padding+2*100, y=uiHeight+padding, width=80, height=uiHeight)


hint2 = tk.Label(root, text="PNG图片路径 ")
hint2.place(x=padding, y=2*uiHeight+2*padding, width=100, height=uiHeight)

entry_dir=tk.Entry(root,bd=2)
entry_dir.place(x=padding+100, y=2*uiHeight+2*padding, width=300, height=uiHeight)



btn = tk.Button(root, text ="选择...", command=lambda :open_img_dir(entry_dir))
btn.place(x=2*padding+100+300, y=2*uiHeight+2*padding, width=50, height=uiHeight)


btn_start = tk.Button(root, text ="开始压缩", command=lambda :start_compress(entry_dir,entry_quality))
btn_start.place(x=padding+100, y=3*uiHeight+3*padding, width=150, height=uiHeight)


## 滚动的日志

text = tk.Text(root , bg='black', fg='white')
scrollbar = tk.Scrollbar(root, command=text.yview)
scrollbar.pack(side=tk.RIGHT, fill=tk.Y)
scrollbar.place(x=500-padding, y=4*uiHeight+4*padding, width=10, height=uiHeight)
text.place(x=padding, y=4*uiHeight+4*padding, width=500-2*padding, height=280)



root.mainloop()

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2240388.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

2.索引:MySQL 索引分类

MySQL中的索引是提高数据查询速度的重要工具&#xff0c;就像一本书的目录&#xff0c;可以帮助我们快速定位到所需的内容。选择适合的索引类型对数据库设计和性能优化至关重要。本文将详细介绍MySQL中常见的索引类型&#xff0c;并重点讲解聚集索引和二级索引的概念及应用。 1…

attention 注意力机制 学习笔记-GPT2

注意力机制 这可能是比较核心的地方了。 gpt2 是一个decoder-only模型&#xff0c;也就是仅仅使用decoder层而没有encoder层。 decoder层中使用了masked-attention 来进行注意力计算。在看代码之前&#xff0c;先了解attention-forward的相关背景知识。 在普通的self-atten…

Elasticsearch 8.16:适用于生产的混合对话搜索和创新的向量数据量化,其性能优于乘积量化 (PQ)

作者&#xff1a;来自 Elastic Ranjana Devaji, Dana Juratoni Elasticsearch 8.16 引入了 BBQ&#xff08;Better Binary Quantization - 更好的二进制量化&#xff09;—— 一种压缩向量化数据的创新方法&#xff0c;其性能优于传统方法&#xff0c;例如乘积量化 (Product Qu…

C语言 char 字符串 - C语言零基础入门教程

目录 一.char 字符串简介 二.字符和字符串区别 1.取值范围相同2.字符串由多个字符构成3.字符串和字符使用 printf 函数 三.char 字符串遍历四.猜你喜欢 零基础 C/C 学习路线推荐 : C/C 学习目录 >> C 语言基础入门 一.char 字符串简介 在C 语言中&#xff0c;除了前面介绍…

小程序文件如何直接上传到oss?一篇文章搞定!

文件上传到 OSS 的小程序工具函数 此工具函数 uploadOss 用于在微信小程序中将临时文件上传到阿里云 OSS&#xff08;对象存储服务&#xff09;。它提供了灵活的参数设置&#xff0c;允许自定义文件路径、文件名前缀和文件目录。 目录 环境依赖函数说明参数使用示例注意事项…

使用Spring AI中的RAG技术,实现私有业务领域的大模型系统

前言 在上一篇文章《使用SpringAI快速实现离线/本地大模型应用》中&#xff0c;记录了如何使用SpringAI来调用我们的本地大模型&#xff0c;如何快速搭建一个本地大模型系统&#xff0c;并演示本地大模型的智能对话、图片理解、文生图等功能。 但在前文中&#xff0c;我们把S…

数据分析-系统认识数据分析

目录 数据分析的全貌 观测 实验 应用 数据分析的全貌 观测 实验 应用

4. 查看并更新langgraph节点

导入必要的库和设置工具 首先&#xff0c;我们需要导入一些必要的库&#xff0c;并设置我们的工具。这些工具将用于在Spotify和Apple Music上播放歌曲。 from langchain_openai import ChatOpenAI from langchain_core.tools import tool from langgraph.graph import Messag…

使用Java绘制图片边框,解决微信小程序map组件中marker与label层级关系问题,label增加外边框后显示不能置与marker上面

今天上线的时候发现系统不同显示好像不一样&#xff0c;苹果手机打开的时候是正常的&#xff0c;但是一旦用安卓手机打开就会出现label不置顶的情况。尝试了很多种办法&#xff0c;也在官方查看了map相关的文档&#xff0c;发现并没有给label设置zIndex的属性&#xff0c;只看到…

【专题】计算机网络之网络层

1. 网络层的几个重要概念 1.1 网络层提供的两种服务 (1) 让网络负责可靠交付 计算机网络模仿电信网络&#xff0c;使用面向连接的通信方式。 通信之前先建立虚电路 VC (Virtual Circuit) (即连接)&#xff0c;以保证双方通信所需的一切网络资源。 如果再使用可靠传输的网络…

vTESTstudio系列15--vTESTstudio-Doors的需求和测试用例的管理

最近有朋友在咨询vTESTstudio中怎么去跟Doors里面的需求去做好管理这方面的问题&#xff0c;临时加两篇文章介绍一下,Lets Go!!! 目录 1.Doors的配置&#xff1a; 1.1 安装Doors AddIn for vTESTstudio&#xff1a; 1.2 更新XML脚本&#xff1a; 1.3 导出需求的Trace Item…

波动中的金钥匙:趋势震荡指标——源码公布,仅供学习

趋势与震荡&#xff0c;两者在市场运行中紧密相连&#xff0c;相互影响。趋势往往是震荡累积后的自然延伸&#xff0c;而震荡则常常是趋势形成与调整的前奏。在各类行情与不同时间周期中&#xff0c;当前的震荡不过是更大周期趋势中的一个组成部分&#xff1b;相应的&#xff0…

面试_ABtest原理简介

01 什么是ABtest ABtest来源于假设检验&#xff0c;现有两个随机均匀的有样本组A、B&#xff0c;对其中一个组A做出某种改动&#xff0c;实验结束后分析两组用户行为数据&#xff0c;通过显著性检验&#xff0c;判断这个改动对于我们所关注的核心指标是否有显著的影响&#xf…

‘nodemon‘ 不是内部或外部命令,也不是可运行的程序

解决方法&#xff1a;使用 npx 临时运行 nodemon 如果你不想全局安装 nodemon&#xff0c;你可以使用 npx&#xff08;npm 5.2 及以上版本自带&#xff09;来临时运行 nodemon&#xff1a; npx nodemon server.jsnodemon正常配置 要在开发过程中实现每次修改 Node.js 代码后…

计算机网络基础(3)_应用层自定义协议与序列化

个人主页&#xff1a;C忠实粉丝 欢迎 点赞&#x1f44d; 收藏✨ 留言✉ 加关注&#x1f493;本文由 C忠实粉丝 原创 计算机网络基础(3)_应用层自定义协议与序列化 收录于专栏【计算机网络】 本专栏旨在分享学习计算机网络的一点学习笔记&#xff0c;欢迎大家在评论区交流讨论&a…

E2E、CRC、Checksum、Rollingcounter

文章目录 前言1、E2E2、CRC3、Checksum4、Rollingcounter总结 前言 在专栏文章仿真CAN报文发送的CRC校验算法&#xff08;附CAPL代码&#xff09;和同星TSMaster中如何自定义E2E校验算法中分别给出了CRC算法和E2E校验实现&#xff0c;从中也明白了为什么在测试中需要去做这些仿…

嵌入式硬件杂谈(一)-推挽 开漏 高阻态 上拉电阻

引言&#xff1a;对于嵌入式硬件这个庞大的知识体系而言&#xff0c;太多离散的知识点很容易疏漏&#xff0c;因此对于这些容易忘记甚至不明白的知识点做成一个梳理&#xff0c;供大家参考以及学习&#xff0c;本文主要针对推挽、开漏、高阻态、上拉电阻这些知识点的学习。 目…

二叉树面试题(C 语言)

目录 1. 单值二叉树2. 相同的树3. 对称二叉树4. 二叉树的前序遍历5. 二叉树的中序遍历6. 二叉树的后序遍历7. 另一颗树的子树8. 通过前序遍历返回中序遍历 1. 单值二叉树 题目描述&#xff1a; 如果二叉树每个节点都具有相同的值&#xff0c;那么该二叉树就是单值二叉树。只有…

MFC中Excel的导入以及使用步骤

参考地址 在需要对EXCEL表进行操作的类中添加以下头文件&#xff1a;若出现大量错误将其放入stdafx.h中 #include "resource.h" // 主符号 #include "CWorkbook.h" //单个工作簿 #include "CRange.h" //区域类&#xff0c;对Excel大…

【C++】类中的“默认成员函数“--构造函数、析构函数、拷贝构造、赋值运算符重载

目录 "默认"成员函数 概念引入&#xff1a; 一、构造函数 问题引入&#xff1a; 1&#xff09;构造函数的概念 2&#xff09;构造函数实例 3&#xff09;构造函数的特性 4)关于默认生成的构造函数 (默认构造函数) 默认构造函数未完成初始化工作实例: 二…