安装库
pip install pyqt5 pillow
"""
exp04 -
Author: 16702
Date: 2025/2/7
"""
import sys
from PyQt5.QtWidgets import QApplication, QWidget, QLabel, QVBoxLayout, QHBoxLayout, QPushButton, QLineEdit, QFileDialog, QMessageBox
from PyQt5.QtGui import QPixmap, QImage
from PyQt5.QtCore import Qt, QMimeData
from PIL import Image
import os
class Window(QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle("图片切割工具")
self.setGeometry(100, 100, 800, 600)
self.setupUI()
def setupUI(self):
self.layout = QVBoxLayout()
self.setLayout(self.layout)
# 图片显示区域
self.image_label = QLabel("拖入图片或点击加载图片")
self.image_label.setAlignment(Qt.AlignCenter)
self.layout.addWidget(self.image_label)
# 输入高度区域
self.height_box = QLineEdit()
self.height_box.setPlaceholderText("输入切割高度(默认为200像素)")
self.layout.addWidget(self.height_box)
# 按钮区域
button_layout = QHBoxLayout()
self.load_button = QPushButton("加载图片")
self.load_button.clicked.connect(self.load_image)
button_layout.addWidget(self.load_button)
self.crop_button = QPushButton("开始切割")
self.crop_button.clicked.connect(self.crop_image)
button_layout.addWidget(self.crop_button)
self.layout.addLayout(button_layout)
# 拖放功能
self.image_label.setAcceptDrops(True)
self.image_label.dragEnterEvent = self.dragEnterEvent
self.image_label.dropEvent = self.dropEvent
def dragEnterEvent(self, event):
if event.mimeData().hasUrls:
event.accept()
else:
event.ignore()
def dropEvent(self, event):
urls = event.mimeData().urls()
if urls:
filename = urls[0].toLocalFile()
if filename.lower().endswith(('.png', '.jpg', '.jpeg', '.bmp')):
self.load_image_from_path(filename)
event.accept()
else:
QMessageBox.warning(self, "警告", "请拖入图片文件!")
event.ignore()
else:
event.ignore()
def load_image(self):
filename, _ = QFileDialog.getOpenFileName(self, "加载图片", os.getcwd(), "图片文件 (*.png *.jpg *.jpeg *.bmp)")
if filename:
self.load_image_from_path(filename)
def load_image_from_path(self, filepath):
self.image_path = filepath
self.image_label.setText(os.path.basename(filepath))
self.pixmap = QPixmap(filepath)
self.pixmap_scaled = self.pixmap.scaled(300, 300, Qt.KeepAspectRatio, Qt.SmoothTransformation)
self.image_label.setPixmap(self.pixmap_scaled)
def crop_image(self):
if not hasattr(self, 'image_path'):
QMessageBox.warning(self, "警告", "请先加载图片!")
return
try:
height = int(self.height_box.text())
if height <= 0:
height = 200 # 默认高度
except:
height = 200
img = Image.open(self.image_path)
width, total_height = img.size
num_crops = total_height // height
if total_height % height != 0:
QMessageBox.warning(self, "警告", f"注意:图片高度({total_height}像素)无法完全被{height}整除,最后一张图片可能不完整。")
save_dir = QFileDialog.getExistingDirectory(self, "选择保存路径", os.getcwd())
if not save_dir:
return
try:
for i in range(num_crops):
upper = i * height
lower = upper + height
cropped_img = img.crop((0, upper, width, lower))
output_path = os.path.join(save_dir, f"image_part_{i+1}.png")
cropped_img.save(output_path)
QMessageBox.information(self, "完成", f"成功切割并保存了{num_crops}张图片!")
except Exception as e:
QMessageBox.critical(self, "错误", f"发生错误:{str(e)}")
if __name__ == "__main__":
app = QApplication(sys.argv)
window = Window()
window.show()
sys.exit(app.exec_())