1、库的介绍
我们在日常办公时,经常需要将图片进行修改尺寸,比如上一些网址非常的不便捷,可以利用python+pyqt5写一个方便图片修改尺寸的代码
2、库的安装
库 | 用途 | 安装 |
---|---|---|
pyqt5 | 界面设计 | pip install pyqt5 -i https://pypi.tuna.tsinghua.edu.cn/simple/ |
pillow | 图片处理 | pip install pillow -i https://pypi.tuna.tsinghua.edu.cn/simple/ |
3、代码结构
1. init
- 初始化窗口组件和变量。
- 设置窗口标题、最小宽度,并调用 initui 方法初始化用户界面。
- 初始化一些状态变量,如 width_connected 和 height_connected(用于控制宽度和高度输入框之间的联动),以及图片路径和原始尺寸。
2. initui
构建主窗口的布局和控件。
包括:
- 文件选择区域(按钮和标签)。
- 图片显示区域(支持拖放功能)。
- 宽度和高度输入框。
- 锁定比例复选框。
- 保存按钮和状态标签。
- 设置布局并初始化锁定比例功能。
3. dragenterevent
处理拖拽事件,判断是否允许文件拖放到图片显示区域。
如果拖拽的是文件,则接受该操作。
4. dropevent
处理文件拖放到图片显示区域后的事件。
检查文件类型是否为图片(支持 .png, .jpg, .jpeg, .bmp),如果是,则加载图片。
5. loadimage
加载指定路径的图片。
使用 pillow 库读取图片的原始尺寸,并更新预览图片。
初始化宽度和高度输入框的值为图片的原始尺寸。
启用保存按钮,并在状态标签中显示“图片已加载”。
6. selectimage
打开文件对话框,让用户选择图片文件。
如果用户选择了有效文件,则调用 loadimage 方法加载图片。
7. updatepreview
更新图片预览区域。
根据当前图片路径生成缩略图,并保持宽高比。
8. onlockaspectratiochanged
处理锁定比例复选框的状态变化。
如果勾选了锁定比例:
连接宽度输入框和高度输入框的 textchanged 信号,实现两者联动。
如果取消勾选:
断开宽度和高度输入框的信号连接。
9. updateheightfromwidth
当宽度输入框的值发生变化时,根据锁定比例计算并更新高度输入框的值。
防止递归调用导致死循环(通过临时断开高度输入框的信号连接)。
10. updatewidthfromheight
当高度输入框的值发生变化时,根据锁定比例计算并更新宽度输入框的值。
同样防止递归调用导致死循环。
11. saveimage
保存调整后的图片。
获取用户输入的宽度和高度,检查其有效性。
使用 pillow 库调整图片大小,并通过文件对话框选择保存路径。
如果保存成功,在状态标签中显示保存路径,并弹出提示框。
12. main
程序入口。
创建 qapplication 实例,初始化 resizeimagetool 窗口,并进入主事件循环。
4、完整代码
# -*- coding: utf-8 -*- ''' @project :测试 @file :test1.py @ide :pycharm @author :一晌小贪欢(278865463@qq.com) @date :2025/3/1 21:07 ''' import sys from pyqt5.qtwidgets import (qapplication, qwidget, qvboxlayout, qpushbutton, qlabel, qlineedit, qfiledialog, qhboxlayout, qcheckbox, qmessagebox, qspaceritem, qsizepolicy) from pyqt5.qtgui import qpixmap, qintvalidator, qdragenterevent, qdropevent from pyqt5.qtcore import qt from pil import image class resizeimagetool(qwidget): def __init__(self): super().__init__() self.width_connected = false self.height_connected = false self.preview_size = 400 # 预览图片的最大尺寸 self.initui() def initui(self): self.setwindowtitle('图片大小调整工具') self.setminimumwidth(500) # 设置主布局 self.layout = qvboxlayout() self.layout.setspacing(10) # 添加文件选择区域 file_layout = qhboxlayout() self.selectbtn = qpushbutton('选择图片', self) self.selectbtn.clicked.connect(self.selectimage) self.filepathlabel = qlabel('未选择文件', self) file_layout.addwidget(self.selectbtn) file_layout.addwidget(self.filepathlabel) self.layout.addlayout(file_layout) # 显示图片的label self.imagelabel = qlabel(self) self.imagelabel.setalignment(qt.aligncenter) self.imagelabel.setminimumheight(self.preview_size) self.imagelabel.setacceptdrops(true) # 启用拖放功能 self.imagelabel.dragenterevent = self.dragenterevent self.imagelabel.dropevent = self.dropevent self.layout.addwidget(self.imagelabel) # 设置尺寸输入区域 size_layout = qhboxlayout() # 宽度输入 width_layout = qvboxlayout() self.widthlabel = qlabel('宽度:', self) self.widthinput = qlineedit(self) self.widthinput.setvalidator(qintvalidator(1, 9999)) width_layout.addwidget(self.widthlabel) width_layout.addwidget(self.widthinput) # 高度输入 height_layout = qvboxlayout() self.heightlabel = qlabel('高度:', self) self.heightinput = qlineedit(self) self.heightinput.setvalidator(qintvalidator(1, 9999)) height_layout.addwidget(self.heightlabel) height_layout.addwidget(self.heightinput) size_layout.addlayout(width_layout) size_layout.addlayout(height_layout) self.layout.addlayout(size_layout) # 添加锁定比例复选框 self.lockaspectratiocheckbox = qcheckbox('锁定比例', self) self.lockaspectratiocheckbox.setchecked(true) self.lockaspectratiocheckbox.statechanged.connect(self.onlockaspectratiochanged) self.layout.addwidget(self.lockaspectratiocheckbox) # 添加保存按钮 self.savebtn = qpushbutton('保存调整后的图片', self) self.savebtn.clicked.connect(self.saveimage) self.savebtn.setenabled(false) self.layout.addwidget(self.savebtn) # 添加状态标签 self.statuslabel = qlabel('', self) self.statuslabel.setalignment(qt.aligncenter) self.layout.addwidget(self.statuslabel) # 设置主窗口的布局 self.setlayout(self.layout) # 初始化变量 self.imagepath = none self.originalwidth = none self.originalheight = none # 初始状态下启用锁定比例 self.onlockaspectratiochanged(qt.checked) def dragenterevent(self, event: qdragenterevent): if event.mimedata().hasurls(): event.acceptproposedaction() def dropevent(self, event: qdropevent): if event.mimedata().hasurls(): filepath = event.mimedata().urls()[0].tolocalfile() if filepath.lower().endswith(('.png', '.jpg', '.jpeg', '.bmp')): self.loadimage(filepath) def loadimage(self, filepath): try: self.imagepath = filepath self.filepathlabel.settext(filepath) # 使用pillow库读取图片原始尺寸 img = image.open(filepath) self.originalwidth, self.originalheight = img.size # 更新预览图片 self.updatepreview() # 初始化输入框 self.widthinput.settext(str(self.originalwidth)) self.heightinput.settext(str(self.originalheight)) # 启用保存按钮 self.savebtn.setenabled(true) self.statuslabel.settext('图片已加载') except exception as e: qmessagebox.critical(self, '错误', f'加载图片时出错:{str(e)}') def selectimage(self): filepath, _ = qfiledialog.getopenfilename( self, '选择图片', '', 'images (*.png *.xpm *.jpg *.jpeg *.bmp)' ) if filepath: self.loadimage(filepath) def updatepreview(self): if not self.imagepath: return pixmap = qpixmap(self.imagepath) scaled_pixmap = pixmap.scaled( self.preview_size, self.preview_size, qt.keepaspectratio, qt.smoothtransformation ) self.imagelabel.setpixmap(scaled_pixmap) def onlockaspectratiochanged(self, state): if state == qt.checked: if not self.width_connected: self.widthinput.textchanged.connect(self.updateheightfromwidth) self.width_connected = true if not self.height_connected: self.heightinput.textchanged.connect(self.updatewidthfromheight) self.height_connected = true else: if self.width_connected: self.widthinput.textchanged.disconnect(self.updateheightfromwidth) self.width_connected = false if self.height_connected: self.heightinput.textchanged.disconnect(self.updatewidthfromheight) self.height_connected = false def updateheightfromwidth(self): if not self.originalwidth or not self.originalheight: return try: if self.height_connected: self.heightinput.textchanged.disconnect(self.updatewidthfromheight) width = int(self.widthinput.text() or 0) if width > 0: height = int((self.originalheight / self.originalwidth) * width) self.heightinput.settext(str(height)) if self.height_connected: self.heightinput.textchanged.connect(self.updatewidthfromheight) except valueerror: pass def updatewidthfromheight(self): if not self.originalwidth or not self.originalheight: return try: if self.width_connected: self.widthinput.textchanged.disconnect(self.updateheightfromwidth) height = int(self.heightinput.text() or 0) if height > 0: width = int((self.originalwidth / self.originalheight) * height) self.widthinput.settext(str(width)) if self.width_connected: self.widthinput.textchanged.connect(self.updateheightfromwidth) except valueerror: pass def saveimage(self): if not self.imagepath: return try: width = int(self.widthinput.text()) height = int(self.heightinput.text()) if width <= 0 or height <= 0: raise valueerror("尺寸必须大于0") img = image.open(self.imagepath) img = img.resize((width, height), image.resampling.lanczos) savepath, _ = qfiledialog.getsavefilename( self, '保存图片', '', 'png (*.png);;jpeg (*.jpg *.jpeg);;bmp (*.bmp)' ) if savepath: img.save(savepath) self.statuslabel.settext(f'图片已保存到: {savepath}') qmessagebox.information(self, '成功', '图片保存成功!') except valueerror as e: qmessagebox.warning(self, '警告', f"输入错误:{str(e)}") except exception as e: qmessagebox.critical(self, '错误', f"保存失败:{str(e)}") if __name__ == '__main__': app = qapplication(sys.argv) window = resizeimagetool() window.show() sys.exit(app.exec_())
效果如下
以上就是python+pyqt5开发一个图片尺寸修改器的详细内容,更多关于python图片尺寸修改的资料请关注代码网其它相关文章!
发表评论