Python+PyQt5開發(fā)一個(gè)圖片尺寸修改器
1、庫的介紹
我們?cè)谌粘^k公時(shí),經(jīng)常需要將圖片進(jìn)行修改尺寸,比如上一些網(wǎng)址非常的不便捷,可以利用python+PyQt5寫一個(gè)方便圖片修改尺寸的代碼
2、庫的安裝
庫 | 用途 | 安裝 |
---|---|---|
PyQt5 | 界面設(shè)計(jì) | pip install PyQt5 -i https://pypi.tuna.tsinghua.edu.cn/simple/ |
pillow | 圖片處理 | pip install pillow -i https://pypi.tuna.tsinghua.edu.cn/simple/ |
3、代碼結(jié)構(gòu)
1. init
- 初始化窗口組件和變量。
- 設(shè)置窗口標(biāo)題、最小寬度,并調(diào)用 initUI 方法初始化用戶界面。
- 初始化一些狀態(tài)變量,如 width_connected 和 height_connected(用于控制寬度和高度輸入框之間的聯(lián)動(dòng)),以及圖片路徑和原始尺寸。
2. initUI
構(gòu)建主窗口的布局和控件。
包括:
- 文件選擇區(qū)域(按鈕和標(biāo)簽)。
- 圖片顯示區(qū)域(支持拖放功能)。
- 寬度和高度輸入框。
- 鎖定比例復(fù)選框。
- 保存按鈕和狀態(tài)標(biāo)簽。
- 設(shè)置布局并初始化鎖定比例功能。
3. dragEnterEvent
處理拖拽事件,判斷是否允許文件拖放到圖片顯示區(qū)域。
如果拖拽的是文件,則接受該操作。
4. dropEvent
處理文件拖放到圖片顯示區(qū)域后的事件。
檢查文件類型是否為圖片(支持 .png, .jpg, .jpeg, .bmp),如果是,則加載圖片。
5. loadImage
加載指定路徑的圖片。
使用 Pillow 庫讀取圖片的原始尺寸,并更新預(yù)覽圖片。
初始化寬度和高度輸入框的值為圖片的原始尺寸。
啟用保存按鈕,并在狀態(tài)標(biāo)簽中顯示“圖片已加載”。
6. selectImage
打開文件對(duì)話框,讓用戶選擇圖片文件。
如果用戶選擇了有效文件,則調(diào)用 loadImage 方法加載圖片。
7. updatePreview
更新圖片預(yù)覽區(qū)域。
根據(jù)當(dāng)前圖片路徑生成縮略圖,并保持寬高比。
8. onLockAspectRatioChanged
處理鎖定比例復(fù)選框的狀態(tài)變化。
如果勾選了鎖定比例:
連接寬度輸入框和高度輸入框的 textChanged 信號(hào),實(shí)現(xiàn)兩者聯(lián)動(dòng)。
如果取消勾選:
斷開寬度和高度輸入框的信號(hào)連接。
9. updateHeightFromWidth
當(dāng)寬度輸入框的值發(fā)生變化時(shí),根據(jù)鎖定比例計(jì)算并更新高度輸入框的值。
防止遞歸調(diào)用導(dǎo)致死循環(huán)(通過臨時(shí)斷開高度輸入框的信號(hào)連接)。
10. updateWidthFromHeight
當(dāng)高度輸入框的值發(fā)生變化時(shí),根據(jù)鎖定比例計(jì)算并更新寬度輸入框的值。
同樣防止遞歸調(diào)用導(dǎo)致死循環(huán)。
11. saveImage
保存調(diào)整后的圖片。
獲取用戶輸入的寬度和高度,檢查其有效性。
使用 Pillow 庫調(diào)整圖片大小,并通過文件對(duì)話框選擇保存路徑。
如果保存成功,在狀態(tài)標(biāo)簽中顯示保存路徑,并彈出提示框。
12. main
程序入口。
創(chuàng)建 QApplication 實(shí)例,初始化 ResizeImageTool 窗口,并進(jìn)入主事件循環(huán)。
4、完整代碼
# -*- coding: UTF-8 -*- ''' @Project :測(cè)試 @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 # 預(yù)覽圖片的最大尺寸 self.initUI() def initUI(self): self.setWindowTitle('圖片大小調(diào)整工具') self.setMinimumWidth(500) # 設(shè)置主布局 self.layout = QVBoxLayout() self.layout.setSpacing(10) # 添加文件選擇區(qū)域 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) # 設(shè)置尺寸輸入?yún)^(qū)域 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) # 添加鎖定比例復(fù)選框 self.lockAspectRatioCheckBox = QCheckBox('鎖定比例', self) self.lockAspectRatioCheckBox.setChecked(True) self.lockAspectRatioCheckBox.stateChanged.connect(self.onLockAspectRatioChanged) self.layout.addWidget(self.lockAspectRatioCheckBox) # 添加保存按鈕 self.saveBtn = QPushButton('保存調(diào)整后的圖片', self) self.saveBtn.clicked.connect(self.saveImage) self.saveBtn.setEnabled(False) self.layout.addWidget(self.saveBtn) # 添加狀態(tài)標(biāo)簽 self.statusLabel = QLabel('', self) self.statusLabel.setAlignment(Qt.AlignCenter) self.layout.addWidget(self.statusLabel) # 設(shè)置主窗口的布局 self.setLayout(self.layout) # 初始化變量 self.imagePath = None self.originalWidth = None self.originalHeight = None # 初始狀態(tài)下啟用鎖定比例 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 # 更新預(yù)覽圖片 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, '錯(cuò)誤', f'加載圖片時(shí)出錯(cuò):{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"輸入錯(cuò)誤:{str(e)}") except Exception as e: QMessageBox.critical(self, '錯(cuò)誤', f"保存失敗:{str(e)}") if __name__ == '__main__': app = QApplication(sys.argv) window = ResizeImageTool() window.show() sys.exit(app.exec_())
效果如下
以上就是Python+PyQt5開發(fā)一個(gè)圖片尺寸修改器的詳細(xì)內(nèi)容,更多關(guān)于Python圖片尺寸修改的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Python中g(shù)lob.glob()函數(shù)的使用
glob 模塊用于查找規(guī)定路徑下的文件路徑名,本文主要介紹了Python中g(shù)lob.glob()函數(shù)的使用,具有一定的參考價(jià)值,感興趣的可以了解一下2024-03-03Python數(shù)據(jù)可視化之Pyecharts使用詳解
Pyecharts是一個(gè)由百度開源的、用于生成Echarts圖表的類庫,可以用來進(jìn)行數(shù)據(jù)可視化分析。本文將詳細(xì)講解一下Pyecharts的使用,需要的可以參考一下2022-04-04Python使用Selenium執(zhí)行JavaScript代碼的步驟詳解
Selenium是一個(gè)用于自動(dòng)化瀏覽器操作的工具,可以模擬人工操作,執(zhí)行各種瀏覽器操作,而JavaScript是一種常用的腳本語言,本文將介紹如何在Python中使用Selenium執(zhí)行JavaScript代碼,并給出一些常見的應(yīng)用示例2023-11-11Python編程二分法實(shí)現(xiàn)冒泡算法+快速排序代碼示例
這篇文章主要介紹了Python編程二分法實(shí)現(xiàn)冒泡算法+快速排序代碼示例,具有一定借鑒價(jià)值,需要的朋友可以參考下2018-01-01Python實(shí)現(xiàn)檢測(cè)文件的MD5值來查找重復(fù)文件案例
這篇文章主要介紹了Python實(shí)現(xiàn)檢測(cè)文件的MD5值來查找重復(fù)文件案例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2020-03-03