QLabel在图像上的映射位置

时间:2019-12-15 19:54:47

标签: python python-3.x pyqt pyqt5 crop

我正在尝试使用Qlabels分割图像,将这些Qlabel放置在图像上,然后通过按segment按钮完成分割,我已经完成了裁剪功能,其工作是裁剪图像的结果与图像上标签的确切位置不匹配。

这是我的代码:

def crop(self):
    i=1
    image = self.UserImageLbl.pixmap()

    for label in self.labels:
        currentQRect = label.geometry()
        #pixmap_rect = self.UserImageLbl.geometry()
        tr = QtGui.QTransform()
        r = tr.mapRect(currentQRect)

        cropQPixmap = image.copy(r)
        cropQPixmap.save('OUT '+str(i)+'.png')
        i=i+1

完整代码示例:

from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import QApplication, QLabel, QWidget
from PyQt5.QtGui import QDrag, QPixmap, QPainter, QCursor
from PyQt5.QtCore import QMimeData, Qt

class DraggableLabel(QLabel):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.setStyleSheet("border-color: rgb(238, 0, 0); border-width : 2.0px; border-style:inset; background: transparent;")
        self.origin = None

    def setLimits(self, rect):
        self.limits = rect

    def mousePressEvent(self, event):
        if not self.origin:
            # update the origin point, we'll need that later
            self.origin = self.pos()
        if event.button() == Qt.LeftButton:
            self.mousePos = event.pos()

    def mouseMoveEvent(self, event):
        if event.buttons() == Qt.LeftButton:
            # move the box
            self.move(self.pos() + event.pos() - self.mousePos)

    def mouseReleaseEvent(self, event):
        if event.button() == Qt.LeftButton:
            # if the box is not within the image boundaries, move it
            # back to the original position
            if not self.limits.contains(self.geometry()):
                self.move(self.origin)


class Ui_Dialog(object):
    def setupUi(self, Dialog):
        Dialog.setObjectName("Dialog")
        Dialog.setEnabled(True)
        Dialog.resize(1050, 800)
        Dialog.setMinimumSize(QtCore.QSize(1050, 800))
        Dialog.setMaximumSize(QtCore.QSize(1050, 800))
        icon = QtGui.QIcon()
        icon.addPixmap(QtGui.QPixmap("../.designer/backup/project pic/images icon.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
        Dialog.setWindowIcon(icon)
        Dialog.setStyleSheet("background-color: rgb(217, 217, 217);\n"
"background-color: rgb(243, 243, 243);")
        self.BrowesImageButton = QtWidgets.QPushButton(Dialog)
        self.BrowesImageButton.setGeometry(QtCore.QRect(820, 60, 200, 60))
        self.BrowesImageButton.setMinimumSize(QtCore.QSize(200, 60))
        self.BrowesImageButton.setMaximumSize(QtCore.QSize(200, 60))
        font = QtGui.QFont()
        font.setFamily("Microsoft YaHei UI")
        font.setPointSize(11)
        font.setBold(True)
        font.setWeight(75)

        self.BrowesImageButton.setFont(font)
        self.BrowesImageButton.setStyleSheet("")
        self.BrowesImageButton.setCheckable(True)
        self.BrowesImageButton.setObjectName("BrowesImageButton")
        self.groupBox = QtWidgets.QGroupBox(Dialog)
        self.groupBox.setGeometry(QtCore.QRect(820, 170, 211, 131))
        font = QtGui.QFont()
        font.setFamily("Microsoft YaHei")
        font.setPointSize(10)
        font.setBold(True)
        font.setWeight(75)
        self.groupBox.setFont(font)
        self.groupBox.setLayoutDirection(QtCore.Qt.LeftToRight)
        self.groupBox.setObjectName("groupBox")
        self.checkBox_Short = QtWidgets.QCheckBox(self.groupBox)
        self.checkBox_Short.setGeometry(QtCore.QRect(20, 40, 141, 23))
        font = QtGui.QFont()
        font.setFamily("Adobe Heiti Std R")
        font.setPointSize(10)

        self.checkBox_Short.setFont(font)
        self.checkBox_Short.setLayoutDirection(QtCore.Qt.LeftToRight)
        self.checkBox_Short.setObjectName("checkBox_Short")
        self.checkBox_Short.setEnabled(False)

        self.checkBox_Long = QtWidgets.QCheckBox(self.groupBox)
        self.checkBox_Long.setGeometry(QtCore.QRect(20, 80, 141, 23))
        font = QtGui.QFont()
        font.setFamily("Adobe Heiti Std R")
        font.setPointSize(10)

        self.checkBox_Long.setFont(font)
        self.checkBox_Long.setLayoutDirection(QtCore.Qt.LeftToRight)
        self.checkBox_Long.setObjectName("checkBox_Long")
        self.checkBox_Long.setEnabled(False)

        self.SegmentImageButton = QtWidgets.QPushButton(Dialog)
        self.SegmentImageButton.setGeometry(QtCore.QRect(830, 330, 200, 60))
        self.SegmentImageButton.setMinimumSize(QtCore.QSize(200, 60))
        self.SegmentImageButton.setMaximumSize(QtCore.QSize(200, 60))

        font = QtGui.QFont()
        font.setFamily("Microsoft YaHei UI")
        font.setPointSize(11)
        font.setBold(True)
        font.setWeight(75)
        self.SegmentImageButton.setFont(font)
        self.SegmentImageButton.setStyleSheet("")
        self.SegmentImageButton.setCheckable(True)
        self.SegmentImageButton.setObjectName("SegmentImageButton")
        self.SegmentImageButton.setEnabled(False)

        self.UserImageLbl = QtWidgets.QLabel(Dialog)
        self.UserImageLbl.setGeometry(QtCore.QRect(40, 40, 750, 500))
        self.UserImageLbl.setMinimumSize(QtCore.QSize(750, 500))
        self.UserImageLbl.setMaximumSize(QtCore.QSize(750, 500))
        self.UserImageLbl.setFrameShape(QtWidgets.QFrame.StyledPanel)
        self.UserImageLbl.setFrameShadow(QtWidgets.QFrame.Plain)
        self.UserImageLbl.setLineWidth(1)
        self.UserImageLbl.setMidLineWidth(0)
        self.UserImageLbl.setText("")
        self.UserImageLbl.setScaledContents(False)
        self.UserImageLbl.setAlignment(QtCore.Qt.AlignCenter)
        self.UserImageLbl.setObjectName("UserImageLbl")

        self.buttonGroup = QtWidgets.QButtonGroup()
        self.buttonGroup.addButton(self.checkBox_Short)
        self.buttonGroup.addButton(self.checkBox_Long)

        self.label_1 = DraggableLabel(Dialog)
        self.label_2 = DraggableLabel(Dialog)
        self.label_3 = DraggableLabel(Dialog)

        self.label_1.move(820, 470)
        self.label_2.move(900, 470)
        self.label_3.move(980, 470)

        self.labels = [self.label_1, self.label_2, self.label_3]
        for label in self.labels:
            label.hide()
            label.raise_()

        self.BrowesImageButton.clicked.connect(self.setImage)
        self.checkBox_Long.toggled.connect(self.setBoxSizes)
        self.checkBox_Short.toggled.connect(self.setBoxSizes)
        self.SegmentImageButton.clicked.connect(self.crop)


    def retranslateUi(self, Dialog):
        _translate = QtCore.QCoreApplication.translate
        Dialog.setWindowTitle(_translate("Dialog", "Cropping"))
        self.BrowesImageButton.setText(_translate("Dialog", "Select Image"))
        self.groupBox.setTitle(_translate("Dialog", "Choose Type"))
        self.checkBox_Short.setText(_translate("Dialog", "Short "))
        self.checkBox_Long.setText(_translate("Dialog", "Long "))
        self.SegmentImageButton.setText(_translate("Dialog", "Segment Image"))

    def setImage(self):
        fileName, _ = QtWidgets.QFileDialog.getOpenFileName(None, "Select Image", "", "Image Files (*.png *.jpg *jpeg *.bmp)") # Ask for file

        if fileName: # If the user gives a file
            pixmap = QtGui.QPixmap(fileName) # Setup pixmap with the provided image
            pixmap = pixmap.scaled(self.UserImageLbl.width(), self.UserImageLbl.height(), QtCore.Qt.KeepAspectRatio) # Scale pixmap
            self.UserImageLbl.setPixmap(pixmap) # Set the pixmap onto the label
            self.UserImageLbl.setAlignment(QtCore.Qt.AlignCenter) # Align the label to center
            #UserImageLbl = DropLabel()
            self.checkBox_Short.setEnabled(True)
            self.checkBox_Long.setEnabled(True)

    def setBoxSizes(self):
        if self.checkBox_Short.isChecked():
            self.SegmentImageButton.setEnabled(True)
            boxSize = 80
        else:
            boxSize = 60
            self.SegmentImageButton.setEnabled(True)


        for label in self.labels:
            label.setFixedSize(boxSize, boxSize)
            label.setLimits(self.UserImageLbl.geometry())
            label.show()

    def crop(self):
        i=1
        image = self.UserImageLbl.pixmap()

        for label in self.labels:
            currentQRect = label.geometry()
            #pixmap_rect = self.UserImageLbl.geometry()
            tr = QtGui.QTransform()
            r = tr.mapRect(currentQRect)

            cropQPixmap = image.copy(r)
            cropQPixmap.save('OUT '+str(i)+'.png')
            i=i+1


if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    Dialog = QtWidgets.QDialog()
    ui = Ui_Dialog()
    ui.setupUi(Dialog)
    Dialog.show()
    sys.exit(app.exec_())

有人可以告诉我我的代码有什么问题! 谢谢

1 个答案:

答案 0 :(得分:1)

首先不要修改Qt Designer生成的代码,但必须创建一个从小部件继承的类,并使用生成的类来填充它。

另一方面,考虑到上述方法,比在QPixmap中制作作物更简单的解决方案是记录窗口的一部分。

from PyQt5 import QtCore, QtGui, QtWidgets


class DraggableLabel(QtWidgets.QLabel):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.setStyleSheet(
            "border-color: rgb(238, 0, 0); border-width : 2.0px; border-style:inset; background: transparent;"
        )
        self.origin = QtCore.QPoint()

    def setLimits(self, rect):
        self.limits = rect

    def mousePressEvent(self, event):
        if self.origin.isNull():
            self.origin = self.pos()
        if event.button() == QtCore.Qt.LeftButton:
            self.mousePos = event.pos()

    def mouseMoveEvent(self, event):
        if event.buttons() == QtCore.Qt.LeftButton:
            self.move(self.pos() + event.pos() - self.mousePos)

    def mouseReleaseEvent(self, event):
        if event.button() == QtCore.Qt.LeftButton:
            if not self.limits.contains(self.geometry()):
                self.move(self.origin)


class Ui_Dialog(object):
    def setupUi(self, Dialog):
        Dialog.setObjectName("Dialog")
        Dialog.setEnabled(True)
        Dialog.resize(1050, 800)
        Dialog.setMinimumSize(QtCore.QSize(1050, 800))
        Dialog.setMaximumSize(QtCore.QSize(1050, 800))
        icon = QtGui.QIcon()
        icon.addPixmap(
            QtGui.QPixmap("../.designer/backup/project pic/images icon.png"),
            QtGui.QIcon.Normal,
            QtGui.QIcon.Off,
        )
        Dialog.setWindowIcon(icon)
        Dialog.setStyleSheet(
            "background-color: rgb(217, 217, 217);\n"
            "background-color: rgb(243, 243, 243);"
        )
        self.BrowesImageButton = QtWidgets.QPushButton(Dialog)
        self.BrowesImageButton.setGeometry(QtCore.QRect(820, 60, 200, 60))
        self.BrowesImageButton.setMinimumSize(QtCore.QSize(200, 60))
        self.BrowesImageButton.setMaximumSize(QtCore.QSize(200, 60))
        font = QtGui.QFont()
        font.setFamily("Microsoft YaHei UI")
        font.setPointSize(11)
        font.setBold(True)
        font.setWeight(75)

        self.BrowesImageButton.setFont(font)
        self.BrowesImageButton.setStyleSheet("")
        self.BrowesImageButton.setCheckable(True)
        self.BrowesImageButton.setObjectName("BrowesImageButton")
        self.groupBox = QtWidgets.QGroupBox(Dialog)
        self.groupBox.setGeometry(QtCore.QRect(820, 170, 211, 131))
        font = QtGui.QFont()
        font.setFamily("Microsoft YaHei")
        font.setPointSize(10)
        font.setBold(True)
        font.setWeight(75)
        self.groupBox.setFont(font)
        self.groupBox.setLayoutDirection(QtCore.Qt.LeftToRight)
        self.groupBox.setObjectName("groupBox")
        self.checkBox_Short = QtWidgets.QCheckBox(self.groupBox)
        self.checkBox_Short.setGeometry(QtCore.QRect(20, 40, 141, 23))
        font = QtGui.QFont()
        font.setFamily("Adobe Heiti Std R")
        font.setPointSize(10)

        self.checkBox_Short.setFont(font)
        self.checkBox_Short.setLayoutDirection(QtCore.Qt.LeftToRight)
        self.checkBox_Short.setObjectName("checkBox_Short")
        self.checkBox_Short.setEnabled(False)

        self.checkBox_Long = QtWidgets.QCheckBox(self.groupBox)
        self.checkBox_Long.setGeometry(QtCore.QRect(20, 80, 141, 23))
        font = QtGui.QFont()
        font.setFamily("Adobe Heiti Std R")
        font.setPointSize(10)

        self.checkBox_Long.setFont(font)
        self.checkBox_Long.setLayoutDirection(QtCore.Qt.LeftToRight)
        self.checkBox_Long.setObjectName("checkBox_Long")
        self.checkBox_Long.setEnabled(False)

        self.SegmentImageButton = QtWidgets.QPushButton(Dialog)
        self.SegmentImageButton.setGeometry(QtCore.QRect(830, 330, 200, 60))
        self.SegmentImageButton.setMinimumSize(QtCore.QSize(200, 60))
        self.SegmentImageButton.setMaximumSize(QtCore.QSize(200, 60))

        font = QtGui.QFont()
        font.setFamily("Microsoft YaHei UI")
        font.setPointSize(11)
        font.setBold(True)
        font.setWeight(75)
        self.SegmentImageButton.setFont(font)
        self.SegmentImageButton.setStyleSheet("")
        self.SegmentImageButton.setCheckable(True)
        self.SegmentImageButton.setObjectName("SegmentImageButton")
        self.SegmentImageButton.setEnabled(False)

        self.UserImageLbl = QtWidgets.QLabel(Dialog)
        self.UserImageLbl.setGeometry(QtCore.QRect(40, 40, 750, 500))
        self.UserImageLbl.setMinimumSize(QtCore.QSize(750, 500))
        self.UserImageLbl.setMaximumSize(QtCore.QSize(750, 500))
        self.UserImageLbl.setFrameShape(QtWidgets.QFrame.StyledPanel)
        self.UserImageLbl.setFrameShadow(QtWidgets.QFrame.Plain)
        self.UserImageLbl.setLineWidth(1)
        self.UserImageLbl.setMidLineWidth(0)
        self.UserImageLbl.setText("")
        self.UserImageLbl.setScaledContents(False)
        self.UserImageLbl.setAlignment(QtCore.Qt.AlignCenter)
        self.UserImageLbl.setObjectName("UserImageLbl")

        self.buttonGroup = QtWidgets.QButtonGroup()
        self.buttonGroup.addButton(self.checkBox_Short)
        self.buttonGroup.addButton(self.checkBox_Long)

        self.retranslateUi(Dialog)

    def retranslateUi(self, Dialog):
        _translate = QtCore.QCoreApplication.translate
        Dialog.setWindowTitle(_translate("Dialog", "Cropping"))
        self.BrowesImageButton.setText(_translate("Dialog", "Select Image"))
        self.groupBox.setTitle(_translate("Dialog", "Choose Type"))
        self.checkBox_Short.setText(_translate("Dialog", "Short "))
        self.checkBox_Long.setText(_translate("Dialog", "Long "))
        self.SegmentImageButton.setText(_translate("Dialog", "Segment Image"))


class Dialog(QtWidgets.QDialog, Ui_Dialog):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.setupUi(self)

        self.label_1 = DraggableLabel(self)
        self.label_2 = DraggableLabel(self)
        self.label_3 = DraggableLabel(self)

        self.label_1.move(820, 470)
        self.label_2.move(900, 470)
        self.label_3.move(980, 470)

        self.labels = [self.label_1, self.label_2, self.label_3]
        for label in self.labels:
            label.hide()
            label.raise_()

        self.BrowesImageButton.clicked.connect(self.setImage)
        self.checkBox_Long.toggled.connect(self.setBoxSizes)
        self.checkBox_Short.toggled.connect(self.setBoxSizes)
        self.SegmentImageButton.clicked.connect(self.crop)

    def setImage(self):
        fileName, _ = QtWidgets.QFileDialog.getOpenFileName(
            None, "Select Image", "", "Image Files (*.png *.jpg *jpeg *.bmp)"
        )  # Ask for file

        if fileName:  # If the user gives a file
            pixmap = QtGui.QPixmap(fileName)  # Setup pixmap with the provided image
            pixmap = pixmap.scaled(
                self.UserImageLbl.width(),
                self.UserImageLbl.height(),
                QtCore.Qt.KeepAspectRatio,
            )  # Scale pixmap
            self.UserImageLbl.setPixmap(pixmap)  # Set the pixmap onto the label
            self.UserImageLbl.setAlignment(
                QtCore.Qt.AlignCenter
            )  # Align the label to center
            # UserImageLbl = DropLabel()
            self.checkBox_Short.setEnabled(True)
            self.checkBox_Long.setEnabled(True)

    def setBoxSizes(self):
        if self.checkBox_Short.isChecked():
            self.SegmentImageButton.setEnabled(True)
            boxSize = 80
        else:
            boxSize = 60
            self.SegmentImageButton.setEnabled(True)

        for label in self.labels:
            label.setFixedSize(boxSize, boxSize)
            label.setLimits(self.UserImageLbl.geometry())
            label.show()

    def crop(self):
        base_rect = self.UserImageLbl.geometry()

        for i, label in enumerate(self.labels, 1):

            label_r = label.geometry()
            res_rect = base_rect.intersected(label_r)
            if not res_rect.isNull():
                label.hide()
                pixmap = self.grab(res_rect)
                label.show()
                pixmap.save("OUT{}.png".format(i))


if __name__ == "__main__":
    import sys

    app = QtWidgets.QApplication(sys.argv)
    w = Dialog()
    w.show()
    sys.exit(app.exec_())