好友
阅读权限 10
听众
最后登录 1970-1-1
vocan
发表于 2024-10-16 01:25
可以拖动缩放,九宫格和圆形
九宫格
[Python] 纯文本查看 复制代码
import sys
from PyQt5.QtWidgets import QApplication, QWidget, QLabel, QPushButton, QVBoxLayout, QHBoxLayout, QFileDialog, QMessageBox
from PyQt5.QtGui import QPixmap, QPainter, QPen, QImage
from PyQt5.QtCore import Qt, QPoint, QRect
from datetime import datetime
class ImageSplitter(QWidget):
def __init__(self):
super().__init__()
self.initUI()
self.image = None
self.image_rect = None
self.drag_start = None
self.scale = 1.0
def initUI(self):
self.setWindowTitle('微信朋友圈九宫格图片分割工具by林林柒')
self.setGeometry(100, 100, 650, 700)
self.image_frame = QLabel(self)
self.image_frame.setFixedSize(600, 600)
self.image_frame.setAlignment(Qt.AlignCenter)
self.image_frame.setStyleSheet("border: 1px solid black;")
self.info_label = QLabel(self)
self.info_label.setAlignment(Qt.AlignCenter)
self.note_label = QLabel("备注:可以拖入图片或导入图片,可以拖动和鼠标滚轮缩放进行分割", self)
self.note_label.setAlignment(Qt.AlignCenter)
import_button = QPushButton('导入图片', self)
import_button.clicked.connect(self.importImage)
split_button = QPushButton('分割图片', self)
split_button.clicked.connect(self.splitImage)
button_layout = QHBoxLayout()
button_layout.addWidget(import_button)
button_layout.addWidget(split_button)
layout = QVBoxLayout()
layout.addWidget(self.image_frame)
layout.addWidget(self.info_label)
layout.addWidget(self.note_label)
layout.addLayout(button_layout)
self.setLayout(layout)
self.setAcceptDrops(True)
def importImage(self):
file_name, _ = QFileDialog.getOpenFileName(self, "选择图片", "", "图片文件 (*.png *.jpg *.bmp)")
if file_name:
self.loadImage(file_name)
def loadImage(self, file_name):
self.image = QImage(file_name)
if self.image.width() < 400 or self.image.height() < 400:
self.info_label.setText("图片大小不能小于400*400")
return
self.scale = min(600 / self.image.width(), 600 / self.image.height())
self.image_rect = QRect(0, 0, self.image.width() * self.scale, self.image.height() * self.scale)
self.updateImage()
self.info_label.setText(f"图片尺寸: {self.image.width()} x {self.image.height()}")
def updateImage(self):
if self.image:
scaled_image = self.image.scaled(self.image_rect.width(), self.image_rect.height(),
Qt.KeepAspectRatio, Qt.SmoothTransformation)
pixmap = QPixmap(600, 600)
pixmap.fill(Qt.white)
painter = QPainter(pixmap)
painter.drawImage(self.image_rect, scaled_image)
self.drawGrid(painter)
painter.end()
self.image_frame.setPixmap(pixmap)
def drawGrid(self, painter):
pen = QPen(Qt.red, 2, Qt.SolidLine)
painter.setPen(pen)
w, h = 600, 600
painter.drawLine(w/3, 0, w/3, h)
painter.drawLine(2*w/3, 0, 2*w/3, h)
painter.drawLine(0, h/3, w, h/3)
painter.drawLine(0, 2*h/3, w, 2*h/3)
def splitImage(self):
if self.image:
save_dir = QFileDialog.getExistingDirectory(self, "选择保存位置", "")
if save_dir:
frame_rect = self.image_frame.rect()
visible_rect = self.image_rect.intersected(frame_rect)
# 计算可见区域在原图中的位置和大小
orig_x = max(0, int((visible_rect.x() - self.image_rect.x()) / self.scale))
orig_y = max(0, int((visible_rect.y() - self.image_rect.y()) / self.scale))
orig_w = min(self.image.width() - orig_x, int(visible_rect.width() / self.scale))
orig_h = min(self.image.height() - orig_y, int(visible_rect.height() / self.scale))
# 生成文件名前缀
date_prefix = datetime.now().strftime("%Y%m%d%H%M%S")
for j in range(3): # 先遍历行
for i in range(3): # 再遍历列
x = orig_x + int(i * orig_w / 3)
y = orig_y + int(j * orig_h / 3)
w = int(orig_w / 3)
h = int(orig_h / 3)
cropped = self.image.copy(x, y, w, h)
file_path = f'{save_dir}/{date_prefix}_{j*3+i+1:02d}.png'
cropped.save(file_path)
QMessageBox.information(self, "完成", f"图片已分割并保存到 {save_dir}")
else:
print("取消保存")
def dragEnterEvent(self, event):
if event.mimeData().hasUrls():
event.accept()
else:
event.ignore()
def dropEvent(self, event):
files = [u.toLocalFile() for u in event.mimeData().urls()]
if files:
self.loadImage(files[0])
def mousePressEvent(self, event):
if self.image and self.image_frame.geometry().contains(event.pos()):
self.drag_start = event.pos()
def mouseMoveEvent(self, event):
if self.drag_start and self.image:
delta = event.pos() - self.drag_start
self.image_rect.translate(delta)
self.drag_start = event.pos()
self.updateImage()
def mouseReleaseEvent(self, event):
self.drag_start = None
def wheelEvent(self, event):
if self.image:
delta = event.angleDelta().y()
if delta > 0:
self.scale *= 1.1
else:
self.scale /= 1.1
self.image_rect.setWidth(int(self.image.width() * self.scale))
self.image_rect.setHeight(int(self.image.height() * self.scale))
self.updateImage()
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = ImageSplitter()
ex.show()
sys.exit(app.exec_())
圆形
[Python] 纯文本查看 复制代码
import sys
from PyQt5.QtWidgets import QApplication, QWidget, QLabel, QPushButton, QVBoxLayout, QHBoxLayout, QFileDialog, QMessageBox
from PyQt5.QtGui import QPixmap, QPainter, QPen, QImage, QColor, QBrush
from PyQt5.QtCore import Qt, QPoint, QRect
from datetime import datetime
class ImageSplitter(QWidget):
def __init__(self):
super().__init__()
self.initUI()
self.image = None
self.image_rect = None
self.drag_start = None
self.scale = 1.0
def initUI(self):
self.setWindowTitle('微信朋友圈九宫格图片分割工具by林林柒')
self.setGeometry(100, 100, 650, 700)
self.image_frame = QLabel(self)
self.image_frame.setFixedSize(600, 600)
self.image_frame.setAlignment(Qt.AlignCenter)
self.image_frame.setStyleSheet("border: 1px solid black;")
self.info_label = QLabel(self)
self.info_label.setAlignment(Qt.AlignCenter)
self.note_label = QLabel("备注:可以拖入图片或导入图片,可以拖动和鼠标滚轮缩放进行分割", self)
self.note_label.setAlignment(Qt.AlignCenter)
import_button = QPushButton('导入图片', self)
import_button.clicked.connect(self.importImage)
split_button = QPushButton('分割图片', self)
split_button.clicked.connect(self.splitImage)
button_layout = QHBoxLayout()
button_layout.addWidget(import_button)
button_layout.addWidget(split_button)
layout = QVBoxLayout()
layout.addWidget(self.image_frame)
layout.addWidget(self.info_label)
layout.addWidget(self.note_label)
layout.addLayout(button_layout)
self.setLayout(layout)
self.setAcceptDrops(True)
def importImage(self):
file_name, _ = QFileDialog.getOpenFileName(self, "选择图片", "", "图片文件 (*.png *.jpg *.bmp)")
if file_name:
self.loadImage(file_name)
def loadImage(self, file_name):
self.image = QImage(file_name)
if self.image.width() < 400 or self.image.height() < 400:
self.info_label.setText("图片大小不能小于400*400")
return
self.scale = min(600 / self.image.width(), 600 / self.image.height())
self.image_rect = QRect(0, 0, self.image.width() * self.scale, self.image.height() * self.scale)
self.updateImage()
self.info_label.setText(f"图片尺寸: {self.image.width()} x {self.image.height()}")
def updateImage(self):
if self.image:
scaled_image = self.image.scaled(self.image_rect.width(), self.image_rect.height(),
Qt.KeepAspectRatio, Qt.SmoothTransformation)
pixmap = QPixmap(600, 600)
pixmap.fill(Qt.white)
painter = QPainter(pixmap)
painter.drawImage(self.image_rect, scaled_image)
self.drawGrid(painter)
painter.end()
self.image_frame.setPixmap(pixmap)
def drawGrid(self, painter):
w, h = 600, 600
# 绘制圆形
pen = QPen(Qt.blue, 4, Qt.SolidLine)
painter.setPen(pen)
painter.setBrush(Qt.transparent)
painter.drawEllipse(0, 0, w, h)
# 绘制网格线
pen = QPen(Qt.red, 2, Qt.SolidLine)
painter.setPen(pen)
painter.drawLine(w/3, 0, w/3, h)
painter.drawLine(2*w/3, 0, 2*w/3, h)
painter.drawLine(0, h/3, w, h/3)
painter.drawLine(0, 2*h/3, w, 2*h/3)
# 添加半透明遮罩
mask = QImage(w, h, QImage.Format_ARGB32_Premultiplied)
mask.fill(Qt.transparent)
mask_painter = QPainter(mask)
mask_painter.setBrush(QColor(255, 255, 255, 128))
mask_painter.setPen(Qt.NoPen)
mask_painter.drawRect(0, 0, w, h)
mask_painter.setCompositionMode(QPainter.CompositionMode_DestinationOut)
mask_painter.setBrush(Qt.black)
mask_painter.drawEllipse(0, 0, w, h)
mask_painter.end()
painter.drawImage(0, 0, mask)
def splitImage(self):
if self.image:
save_dir = QFileDialog.getExistingDirectory(self, "选择保存位置", "")
if save_dir:
frame_rect = self.image_frame.rect()
visible_rect = self.image_rect.intersected(frame_rect)
# 计算可见区域在原图中的位置和大小
orig_x = max(0, int((visible_rect.x() - self.image_rect.x()) / self.scale))
orig_y = max(0, int((visible_rect.y() - self.image_rect.y()) / self.scale))
orig_w = min(self.image.width() - orig_x, int(visible_rect.width() / self.scale))
orig_h = min(self.image.height() - orig_y, int(visible_rect.height() / self.scale))
# 生成文件名前缀
date_prefix = datetime.now().strftime("%Y%m%d%H%M%S")
# 创建圆形遮罩
mask = QImage(orig_w, orig_h, QImage.Format_ARGB32_Premultiplied)
mask.fill(Qt.transparent)
mask_painter = QPainter(mask)
mask_painter.setBrush(Qt.white)
mask_painter.setPen(Qt.NoPen)
mask_painter.drawEllipse(0, 0, orig_w, orig_h)
mask_painter.end()
# 应用遮罩到整个图像,并用白色填充透明部分
result = QImage(orig_w, orig_h, QImage.Format_RGB32)
result.fill(Qt.white)
result_painter = QPainter(result)
result_painter.setCompositionMode(QPainter.CompositionMode_SourceOver)
result_painter.drawImage(0, 0, self.image.copy(orig_x, orig_y, orig_w, orig_h))
result_painter.setCompositionMode(QPainter.CompositionMode_DestinationIn)
result_painter.drawImage(0, 0, mask)
result_painter.setCompositionMode(QPainter.CompositionMode_DestinationOver)
result_painter.fillRect(result.rect(), Qt.white)
result_painter.end()
# 分割圆形图像
for j in range(3):
for i in range(3):
x = int(i * orig_w / 3)
y = int(j * orig_h / 3)
w = int(orig_w / 3)
h = int(orig_h / 3)
cropped = result.copy(x, y, w, h)
file_path = f'{save_dir}/{date_prefix}_{j*3+i+1:02d}.jpg'
cropped.save(file_path, 'JPEG', 100)
QMessageBox.information(self, "完成", f"圆形图片已分割并保存到 {save_dir}")
else:
print("取消保存")
def dragEnterEvent(self, event):
if event.mimeData().hasUrls():
event.accept()
else:
event.ignore()
def dropEvent(self, event):
files = [u.toLocalFile() for u in event.mimeData().urls()]
if files:
self.loadImage(files[0])
def mousePressEvent(self, event):
if self.image and self.image_frame.geometry().contains(event.pos()):
self.drag_start = event.pos()
def mouseMoveEvent(self, event):
if self.drag_start and self.image:
delta = event.pos() - self.drag_start
self.image_rect.translate(delta)
self.drag_start = event.pos()
self.updateImage()
def mouseReleaseEvent(self, event):
self.drag_start = None
def wheelEvent(self, event):
if self.image:
delta = event.angleDelta().y()
if delta > 0:
self.scale *= 1.1
else:
self.scale /= 1.1
self.image_rect.setWidth(int(self.image.width() * self.scale))
self.image_rect.setHeight(int(self.image.height() * self.scale))
self.updateImage()
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = ImageSplitter()
ex.show()
sys.exit(app.exec_())
免费评分
查看全部评分