当前位置: 代码网 > it编程>前端脚本>Python > Python+PyQt5开发一个图片尺寸修改器

Python+PyQt5开发一个图片尺寸修改器

2025年03月03日 Python 我要评论
1、库的介绍我们在日常办公时,经常需要将图片进行修改尺寸,比如上一些网址非常的不便捷,可以利用python+pyqt5写一个方便图片修改尺寸的代码2、库的安装库用途安装pyqt5界面设计pip ins

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图片尺寸修改的资料请关注代码网其它相关文章!

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com