python之pyqt5-第一个pyqt5程序-图像压缩工具(2.0版本)-小记

python之pyqt5-第一个pyqt5程序-图像压缩工具(2.0版本)-小记

此篇为上一篇pyqt5图像压缩小工具改良版。因为比较简单,下面直接贴上代码。

效果图:

 

# -*- coding: utf-8 -*-# Form implementation generated from reading ui file 'hellopyqt5.ui'
#
# Created by: PyQt5 UI code generator 5.11.3
#
# WARNING! All changes made in this file will be lost!
import os
import sys
import zlib
#import resource 图标资源可不要
from os import path
from PIL import Image
from glob import glob
from PyQt5.QtGui import QIcon
from PyQt5.QtGui import QFont
from PyQt5.QtWidgets import QFileDialog
from PyQt5.QtWidgets import QMessageBox
from PyQt5.QtWidgets import QMainWindow
from PyQt5.QtWidgets import QFrame
from PyQt5 import QtCore, QtGui, QtWidgetsclass Ui_Form(QMainWindow):def __init__(self):super(QtWidgets.QMainWindow,self).__init__()self.setupUi(self)self.retranslateUi(self)def setupUi(self, Form):Form.setObjectName("Form")Form.resize(368, 290)Form.setFixedSize(368, 260)Form.setWindowTitle('图像压缩工具')#图标#Form.setWindowIcon(QIcon(':/1.png'))
        self.tabWidget = QtWidgets.QTabWidget(Form)self.tabWidget.setGeometry(QtCore.QRect(10, 10, 351, 271))self.tabWidget.setObjectName("tabWidget")self.tab = QtWidgets.QWidget()#指定显示特定tab #self.tab.setCurrentIndex(0)self.tab.setObjectName("tab")self.pushButton_4 = QtWidgets.QPushButton(self.tab)self.pushButton_4.setGeometry(QtCore.QRect(100, 120, 141, 41))self.pushButton_4.setObjectName("pushButton_4")#无损选择文件夹
        self.pushButton_4.clicked.connect(self.opendicno)self.pushButton_3 = QtWidgets.QPushButton(self.tab)self.pushButton_3.setGeometry(QtCore.QRect(120, 70, 101, 41))self.pushButton_3.setObjectName("pushButton_3")#无损选择文件
        self.pushButton_3.clicked.connect(self.openpicno)self.label = QtWidgets.QLabel(self.tab)self.label.setGeometry(QtCore.QRect(20, 10, 281, 51))self.label.setTextFormat(QtCore.Qt.AutoText)self.label.setWordWrap(True)self.label.setObjectName("label")self.tabWidget.addTab(self.tab, "")self.tab_2 = QtWidgets.QWidget()self.tab_2.setObjectName("tab_2")self.pushButton = QtWidgets.QPushButton(self.tab_2)self.pushButton.setGeometry(QtCore.QRect(120, 70, 101, 41))self.pushButton.setCheckable(False)self.pushButton.setObjectName("pushButton")#有损压缩打开文件
        self.pushButton.clicked.connect(self.openfile)self.pushButton_2 = QtWidgets.QPushButton(self.tab_2)self.pushButton_2.setGeometry(QtCore.QRect(100, 120, 141, 41))self.pushButton_2.setCheckable(False)self.pushButton_2.setObjectName("pushButton_2")#有损压缩打开文件夹
        self.pushButton_2.clicked.connect(self.opendic)#frame和radiobuttonself.frame = QtWidgets.QFrame(self.tab_2)self.frame.setGeometry(QtCore.QRect(0, 160, 341, 71))self.frame.setFrameShape(QtWidgets.QFrame.StyledPanel)self.frame.setFrameShadow(QtWidgets.QFrame.Raised)self.frame.setObjectName("frame") self.frame.setStyleSheet('background-color:#FAEBD7;')self.frame.setFrameShape(QFrame.Box)self.frame.setLineWidth(2)self.radioButton = QtWidgets.QRadioButton(self.frame)self.radioButton.setGeometry(QtCore.QRect(20, 40, 51, 16))self.radioButton.setObjectName("radioButton")self.radioButton_2 = QtWidgets.QRadioButton(self.frame)self.radioButton_2.setGeometry(QtCore.QRect(100, 40, 51, 16))self.radioButton_2.setObjectName("radioButton_2")self.radioButton_3 = QtWidgets.QRadioButton(self.frame)self.radioButton_3.setGeometry(QtCore.QRect(190, 40, 51, 16))self.radioButton_3.setObjectName("radioButton_3")self.radioButton_4 = QtWidgets.QRadioButton(self.frame)self.radioButton_4.setGeometry(QtCore.QRect(280, 40, 51, 16))self.radioButton_4.setObjectName("radioButton_4")#toggled信号与槽函数绑定self.radioButton.toggled.connect(lambda :self.btnstate(self.radioButton))self.radioButton_2.toggled.connect(lambda :self.btnstate(self.radioButton_2))self.radioButton_3.toggled.connect(lambda :self.btnstate(self.radioButton_3))self.radioButton_4.toggled.connect(lambda :self.btnstate(self.radioButton_4))#2个labelself.label_3 = QtWidgets.QLabel(self.frame)self.label_3.setGeometry(QtCore.QRect(10, 10, 81, 21))self.label_3.setObjectName("label_3")self.tabWidget.addTab(self.tab_2, "")self.label_2 = QtWidgets.QLabel(self.tab_2)self.label_2.setGeometry(QtCore.QRect(20, 10, 281, 51))self.label_2.setTextFormat(QtCore.Qt.AutoText)self.label_2.setWordWrap(True)self.label_2.setObjectName("label_2")self.tabWidget.addTab(self.tab_2, "")self.tabWidget.setCurrentIndex(0)self.retranslateUi(Form)#原来你在这里#self.tabWidget.setCurrentIndex(1)
        QtCore.QMetaObject.connectSlotsByName(Form)bs=float(0.8)def btnstate(self,btn):global bsif btn.text()=='0.8X':if btn.isChecked()==True:bs=float(0.8)print(bs)else:print("0.8没有被选中")if btn.text()=='0.6X':if btn.isChecked()==True:#global bsbs=float(0.6)print(bs)else:print("0.6没有被选中")if btn.text()=='0.4X':if btn.isChecked()==True:#global bsbs=float(0.4)print(bs)else:print("0.4没有被选中")if btn.text()=='0.2X':if btn.isChecked()==True:#global bsbs=float(0.2)print(bs)else:print("0.2没有被选中")def openfile(self):try:if self.radioButton.isChecked()==True or self.radioButton_2.isChecked()==True or self.radioButton_3.isChecked()==True or self.radioButton_4.isChecked()==True:filename ,filetype = QFileDialog.getOpenFileName(self,"选择文件","./","All Files (*);;Image Files (*.jpg)")if filename != '':path=filename.replace(r'/',r'\\')try:img = Image.open(path) # 打开图片文件if img.width>5:#等比例缩小width=img.widthheight=img.heightsize=(width*bs,height*bs)img.thumbnail(size, Image.ANTIALIAS) # 使用抗锯齿模式生成缩略图(压缩图片)f=os.path.splitext(path)newname=f[0] + '-已压缩'newname=newname+f[1]img.save(newname, "JPEG") # 保存成与原文件名一致的文件,会自动覆盖源文件else:print(file + "宽度小,已忽略")except Exception as e:print(e)QMessageBox.information(self,"恭喜,成功了!", "已成功压缩图片到原有目录",QMessageBox.Yes)#QMessageBox.Yes | QMessageBox.Noelse:QMessageBox.warning(self,"选择压缩比例", "请先选择压缩比例。",QMessageBox.Yes)except Exception as e:print(e)def opendic(self):try:if self.radioButton.isChecked()==True or self.radioButton_2.isChecked()==True or self.radioButton_3.isChecked()==True or self.radioButton_4.isChecked()==True:dic = QFileDialog.getExistingDirectory(self,"选择文件夹", "./")if dic != '':path=dic.replace(r'/',r'\\')# glob.glob()用来进行模糊查询,增加参数recursive=True后可以使用**/来匹配所有子目录files = glob( path + "**/*.JPG", recursive=True) + glob(path + "**/*.jpg", recursive=True)total = len(files) #总文件数cur = 1 #当前文件序号for infile in files:try:print("进度:" + str(cur) + "/" + str(total) + "   " + infile)img = Image.open(infile) # 打开图片文件if img.width>5:width=img.widthheight=img.heightsize=(width*bs,height*bs)img.thumbnail(size, Image.ANTIALIAS) # 使用抗锯齿模式生成缩略图(压缩图片)f=os.path.splitext(infile)newname=f[0] + '-已压缩'newname=newname+f[1]img.save(newname, "JPEG") # infile保存成与原文件名一致的文件,会自动覆盖源文件else:print(infile + "宽度小,无需处理,已忽略")cur = cur + 1except Exception as e:print(e)QMessageBox.information(self,"恭喜,成功了!", "已成功压缩图片到原有目录",QMessageBox.Yes)else:QMessageBox.warning(self,"选择压缩比例", "请先选择压缩比例。",QMessageBox.Yes)except Exception as e:print(e)def openpicno(self):filename ,filetype = QFileDialog.getOpenFileName(self,"选择文件","./","All Files (*);;Image Files (*.jpg)")if filename != '':try:path=filename.replace(r'/',r'\\')im = Image.open(path)  # 打开图片imBytes = im.tobytes()  # 把图片转换成bytes流imBytes = zlib.compress(imBytes, 9)  # 对图像字节串进行压缩,第二个参数是压缩率有-1,0-9,按个人情况进行设置,我都试过了感觉没多大变化,所以随便设置了5im2 = Image.frombytes('RGB', im.size, zlib.decompress(imBytes))  # 压缩成新的图片f=os.path.splitext(path)newname=f[0] + '-已压缩'newname=newname+f[1]im2.save(newname) # 保存成与原文件名一致的文件,会自动覆盖源文件QMessageBox.information(self,"恭喜,成功了!", "已成功压缩图片到原有目录",QMessageBox.Yes)except Exception as e:print(e)def opendicno(self):dic = QFileDialog.getExistingDirectory(self,"选择文件夹", "./")path=dic.replace(r'/',r'\\')if dic != '':path=dic.replace(r'/',r'\\')# glob.glob()用来进行模糊查询,增加参数recursive=True后可以使用**/来匹配所有子目录files = glob( path + "**/*.JPG", recursive=True) + glob(path + "**/*.jpg", recursive=True)total = len(files) #总文件数print(total)cur = 1 #当前文件序号for infile in files:try:im = Image.open(infile) # 打开if im.width>5:imBytes = im.tobytes()imBytes = zlib.compress(imBytes, 9)im2 = Image.frombytes('RGB', im.size, zlib.decompress(imBytes))  # 压缩成新图片#改名------------------------f=os.path.splitext(infile)newname=f[0] + '-已压缩'newname=newname+f[1]#改名------------------------im2.save(newname, "JPEG") # 保存成与原文件名一致的文件,会自动覆盖源文件else:print(infile + "宽度小于1200px,无需处理,已忽略")cur = cur + 1except Exception as e:print(e)QMessageBox.information(self,"恭喜,成功了!", "已成功压缩图片到原有目录",QMessageBox.Yes)def retranslateUi(self, Form):_translate = QtCore.QCoreApplication.translateForm.setWindowTitle(_translate("Form", "图像压缩工具"))self.pushButton_4.setText(_translate("Form", "选择文件夹"))self.pushButton_3.setText(_translate("Form", "选择文件"))self.label.setText(_translate("Form", "注:无损压缩不改变图像分辨率,仅改变DPI,适合10M以上超大图片压缩,如需要进一步压缩,可再进行有损压缩。"))self.label_2.setText(_translate("Form", "注:通过缩小图像分辨率压缩图片。请先选择合适的缩小比例。"))self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab), _translate("Form", "无损压缩"))self.pushButton.setText(_translate("Form", "选择文件"))self.pushButton_2.setText(_translate("Form", "选择文件夹"))self.radioButton.setText(_translate("Form", "0.8X"))self.radioButton_2.setText(_translate("Form", "0.6X"))self.radioButton_3.setText(_translate("Form", "0.4X"))self.radioButton_4.setText(_translate("Form", "0.2X"))self.label_3.setText(_translate("Form", "选择压缩比例"))self.label_3.setToolTip(_translate("Form", "<html><head/><body><p>手动指定压缩分辨率</p></body></html>"))self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_2), _translate("Form", "有损压缩")) #
        self.tabWidget.setCurrentIndex(self.tabWidget.indexOf(self.tab))if __name__ == '__main__':  app = QtWidgets.QApplication(sys.argv)Form = QtWidgets.QMainWindow()ui = Ui_Form()ui.setupUi(Form)Form.show()sys.exit(app.exec_())

 

posted on 2019-07-18 18:03 蓝皮阿五 阅读(...) 评论(...) 编辑 收藏

转载于:https://www.cnblogs.com/lanpiawu/p/11209044.html

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

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

相关文章

c++面试题(1)

1. 构造函数与析构函数是否可以被重载&#xff0c;为什么&#xff1f; 2. 指针和引用的区别。 3. malloc和new的区别。 4. 字符串反转。用两种方法&#xff0c;第二种方法只用一个数串&#xff0c;直接互换。 5. 一个time类&#xff0c;包含minu…

开发人员需要了解的有关xPaaS的一切

最近&#xff0c;我一直在阅读有关Red Hat产品的很多文章&#xff0c;并且对云等也很感兴趣&#xff0c;对于我来说&#xff0c;更详细地研究Red Hat的云产品是很明显的。 Arun在今年4月对JBoss xPaaS进行了很好的概述&#xff0c;我认为可能不但应该给您一个概述&#xff0c;而…

Mybatis与Spring整合

Mybatis与Spring整合 既然我们已经学了Mybatis的基本开发了&#xff0c;接下来就是Mybatis与Spring的整合了&#xff01; 以下使用的是Oracle数据库来进行测试 导入jar包 aopalliance.jarasm-3.3.1.jaraspectjweaver.jarc3p0-0.9.1.2.jarcglib-2.2.2.jarcommons-logging.ja…

算法与数据结构基础 - 堆(Heap)和优先级队列(Priority Queue)

堆基础 堆(Heap)是具有这样性质的数据结构&#xff1a;1/完全二叉树 2/所有节点的值大于等于(或小于等于)子节点的值&#xff1a; 图片来源&#xff1a;这里 堆可以用数组存储&#xff0c;插入、删除会触发节点shift_down、shift_up操作&#xff0c;时间复杂度O(logn)&#xff…

C++静态数据成员和静态成员函数

在C面向对象编程过程当中&#xff0c;对象与对象之间的数据不是共享&#xff0c;在设计类的时候&#xff0c;有时候需要一些对象之间共享的数据&#xff0c;除了把所要共享的数据设置为全局数据或者函数之外&#xff0c;还可以利用C的静态机制。 1、静态数据成员 class 类名 {…

带有AOP和注释的Java方法记录

有时&#xff0c;我想记录&#xff08;通过slf4j和log4j &#xff09;方法的每次执行&#xff0c;查看其接收的参数&#xff0c;返回的内容以及每次执行需要多少时间。 这是我在AspectJ &#xff0c; jcabi-aspects和Java 6注释的帮助下进行的操作&#xff1a; public class F…

JDBC【介绍JDBC、使用JDBC连接数据库、简单的工具类】

什么是JDBC JDBC全称为&#xff1a;Java Data Base Connectivity,它是可以执行SQL语句的Java API 为什么我们要用JDBC 市面上有非常多的数据库&#xff0c;本来我们是需要根据不同的数据库学习不同的API&#xff0c;sun公司为了简化这个操作&#xff0c;定义了JDBC API【接口…

mysql binlog空间维护

默认情况下&#xff0c;mysql主从同步的binlog日志&#xff0c;会一直保存。 对于如果已同步好的数据&#xff0c;这显然比较浪费资源。 且如果生产环境磁盘太小&#xff0c;随时还会爆掉&#xff0c;所以很有必要作好binlog的空间维护。 以下操作&#xff0c;直接在master上操…

UVA 10604 Chemical Reaction

UVA_10604 一开始看错题了&#xff0c;以为化学物质最多会有10个&#xff0c;所以定义不了10维的去跑&#xff0c;便用了类似状态压缩的方式&#xff0c;把化学物质的状态压缩成一个整数&#xff0c;然后用哈希表建立一个索引&#xff0c;再用记忆化搜素去处理就可以了。 之所以…

一键发布到Maven Central的方法

当我向Maven Central发布Java开源库jcabi-aspects的新版本时&#xff0c;我花费了30秒钟的时间。 甚至更少。 最近&#xff0c;我发布了0.17.2版本。 您可以在Github第80期中看到所有情况&#xff1a; 如您所见&#xff0c;我向Rultor发出了命令&#xff0c;它向Maven Central…

vue组件详解(一)——组件与复用

一、什么是组件 组件 (Component) 是 Vue.js 最强大的功能之一。组件可以扩展 HTML 元素&#xff0c;封装可重用的代码。 二、组件用法 组件需要注册后才可以使用&#xff0c;注册有全局注册和局部注册两种方式。 2.1 全局注册后&#xff0c;任何V ue 实例都可以使用。如&am…

fatal error LNK1120: 1 unresolved externals

出现这个错误可能原因很多&#xff0c;我的问题是来自于把template写在了cpp文件中template 有弊端 就是 他的实现部分必须和声明部分在一起 你声明在一个头文件 定义在另一个头文件 编译器好笨!!!!!!!!!,它根本就找不到 ///只要你把实现部分拷贝到你声明的头文件,就没有错…

sed命令学习

sed编辑器&#xff0c;处理文本过程如下&#xff1a; sed把当前处理的行保存在一个临时缓冲区中&#xff0c;然后处理缓冲区中的行&#xff0c;完成后把该行发送到屏幕上。sed每处理完一行就将其从临时缓冲区删除&#xff0c;然后下一行读入&#xff0c;处理和显示。处理完输入…

在Spring Boot应用程序中测试邮件代码

在构建Spring Boot应用程序时&#xff0c;您可能会需要添加邮件配置。 实际上&#xff0c;在Spring Boot中配置邮件与在Spring Bootless应用程序中配置邮件没有太大区别。 但是&#xff0c;如何测试邮件配置和提交工作正常&#xff1f; 我们来看一下。 我假设我们有一个引导的…

CSS基础语法(三) CSS的6种特性

样式表常用写法及特性&#xff08;组合、继承、关联性、权值性、层叠性、重要性&#xff09; 1.样式的组合&#xff1a;把具有相同声明定义的选择符组合在一起&#xff0c;并用逗号隔开。&#xff0d;例如&#xff1a;段落元素p、单元格元素td和类c1可以使用相同样式&#xff…

卷积,DFT,FFT,图像FFT,FIR 和 IIR 的物理意义

卷积&#xff1a; 冲击信号会对线性系统产生冲击响应。 冲击信号可分解为平移度和幅度。其对线性系统的冲击响应可以分解为点点间的经平移和缩放的各个冲击响应的累加&#xff0c;通过卷积的表达式表示。 所谓的冲击响应&#xff0c;就是线性系统对任何输入信号的响应&#xff…

洛谷P2822 组合数问题

分析&#xff1a; 首先预处理出来&#xff0c;杨辉三角二维前缀和 代码&#xff1a; #include<cstdio> using namespace std; long long f[2005][2005],sum[2005][2005]; int main() {long long T,k;scanf("%lld%lld",&T,&k);for(long long i0;i<20…

es6笔记

es6对象浅复制&#xff1a; 字符串大小比较&#xff1a; 如果是汉字&#xff1a;a.charCodeAt() > b.charCodeAt() //使用carCodeAt将器转为asci码&#xff0c;在进行比较 如果是非汉字的字符串&#xff1a;直接比较或者使用上面的转码比较都可以。 如果是日期比较&#xff…

毕业设计上线啦!----跳蚤部落与基于Comet的WebIM系统开发

我不清楚把我的毕业设计的东西放上来之后&#xff0c;毕业论文答辩的时候会不会说我是在网上抄袭的&#xff0c;不过我还是果断的发上来与大家分享了&#xff01;&#xff01;呵呵&#xff0c;请大家支持&#xff01;高手就绕道吧&#xff01; 现在已经放到公网上&#xff0c;并…

poj2032Square Carpets(IDA* + dancing links)

题目请戳这里 题目大意:给一个H行W列的01矩阵,求最少用多少个正方形框住所有的1. 题目分析:又是一个红果果的重复覆盖模型.DLX搞之! 枚举矩阵所有的子正方形,全1的话建图.判断全1的时候,用了一个递推,dp[i][j][w][h]表示左上角(i,j)的位置开始长h宽w的矩形中1的个数,这样后面可…