在pyq中按选择区域和平移特征缩放

2024-06-16 11:35:03 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在使用pyqt中的橡皮筋功能来选择要缩放的图像区域。我有单选按钮,你可以选择缩放(1)和平移(2)。我目前有它的设置,以便它缩放到正确的比例,但我还没有弄清楚如何使选定区域的中心,然后在缩放完成后,在放大图像的中心。我也不明白为什么平移功能不起作用。我想它会像设置拖动模式为ScrollHandDrag一样简单。你知道吗

这里有一个注释掉的部分,显示了我在缩放后将图像居中的尝试。你知道吗

class GraphicsView(QGraphicsView, photoManager):
    rectChanged = pyqtSignal(QRect)

    def __init__(self, parent = None):
        super(GraphicsView, self).__init__(parent)
        self.parent = parent
        self.button = 0
        self.setGeometry(300, 300, 250, 150)
        self.setScene(GraphicsScene(self))
        self.pixmapItem = QGraphicsPixmapItem() #check if everytime you open a new image the old image is still an item
        self.scene().addItem(self.pixmapItem)
        self._empty = True
        self._path_item = None

        self.rubberBand = QRubberBand(QRubberBand.Rectangle, self)
        self.setMouseTracking(True)
        self.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
        self.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
        self.setTransformationAnchor(QtWidgets.QGraphicsView.AnchorUnderMouse)
        self.setFrameShape(QtWidgets.QFrame.NoFrame)
        self.origin = QPoint()
        self.changeRubberBand = False
        self.initial_path()

    def whichButton(self):
        self.button = self.parent.connectRB()


    def hasPhoto(self):
        return not self._empty

    def initial_path(self):
        self._path = QtGui.QPainterPath()
        pen = QtGui.QPen(QtGui.QColor("green"), 4, QtCore.Qt.SolidLine, QtCore.Qt.RoundCap)
        self._path_item = self.scene().addPath(self._path, pen)

    def setImage(self):
        filename, _ = QFileDialog.getOpenFileName(
            None, "select Image", "", "Image Files (*.png *.jpg *jpg *.bmp *.tif)"
        )
        if filename:
            if self._empty == True:

                self._empty = False
                self.image = QPixmap(filename) #this should not change unless a new image is selected
                width = self.image.width() * 0.3
                height = self.image.height() * 0.3
                self.imageScaled = self.image.scaled(width, height, QtCore.Qt.KeepAspectRatio)
                self.pixmapItem.setPixmap(self.imageScaled)#QtGui.QPixmap(filename))

                self.cvImage = cv2.imread(filename)
                self.cvogImage = cv2.imread(filename)
                self.cvogImageBW = cv2.imread(filename, 0)
                self.cvImageBW = cv2.imread(filename, 0)

            elif self._empty == False:

                self.pixmapItem.clear()
                self.image = QPixmap(filename) #this should not change unless a new image is selected
                width = self.image.width() * 0.3
                height = self.image.height() * 0.3
                self.imageScaled = self.image.scaled(width, height, QtCore.Qt.KeepAspectRatio)
                self.pixmapItem.setPixmap(self.imageScaled)#QtGui.QPixmap(filename))

                self.cvImage = cv2.imread(filename)
                self.cvogImage = cv2.imread(filename)
                self.cvogImageBW = cv2.imread(filename, 0)
                self.cvImageBW = cv2.imread(filename, 0)

    def mousePressEvent(self, event):

        self.whichButton()

        if self.button == 0:

            self.setDragMode(QtWidgets.QGraphicsView.NoDrag)

            start = event.pos()
            if (
                not self.pixmapItem.pixmap().isNull()
                and event.buttons() & Qt.LeftButton
            ):
                self.initial_path()
                self._path.moveTo(self.mapToScene(event.pos()))
                self._path_item.setPath(self._path)
            super(GraphicsView, self).mousePressEvent(event)

        elif self.button == 1:

            self.setDragMode(QtWidgets.QGraphicsView.NoDrag)

            if self.hasPhoto():
                self.origin = event.pos()
                self.rubberBand.setGeometry(QRect(self.origin, QSize()))
                self.rectChanged.emit(self.rubberBand.geometry())
                self.rubberBand.show()
                self.changeRubberBand = True
            QGraphicsView.mousePressEvent(self, event)

            #TODO - make zoom and pan radiobuttons work
        elif self.button == 2:

            self.setDragMode(QtWidgets.QGraphicsView.ScrollHandDrag)

        elif self.button == 3:

            self.setDragMode(QtWidgets.QGraphicsView.NoDrag)
            if self.hasPhoto():
                self.origin = event.pos()
                self.rubberBand.setGeometry(QRect(self.origin, QSize()))
                self.rectChanged.emit(self.rubberBand.geometry())
                self.rubberBand.show()
                self.changeRubberBand = True
            QGraphicsView.mousePressEvent(self, event)

    def mouseMoveEvent(self, event):

        if self.button == 0:

            if (
                not self.pixmapItem.pixmap().isNull()
                and event.buttons() & Qt.LeftButton
                and self._path_item is not None
            ):
                self._path.lineTo(self.mapToScene(event.pos()))
                self._path_item.setPath(self._path)
            super(GraphicsView, self).mousePressEvent(event)

        elif self.button == 1:
            if self.changeRubberBand:
                self.rubberBand.setGeometry(QRect(self.origin, event.pos()).normalized())
                self.rectChanged.emit(self.rubberBand.geometry())
            QGraphicsView.mouseMoveEvent(self, event)

        elif self.button == 3:
            if self.changeRubberBand:
                self.rubberBand.setGeometry(QRect(self.origin, event.pos()).normalized())
                self.rectChanged.emit(self.rubberBand.geometry())
            QGraphicsView.mouseMoveEvent(self, event)



    def mouseReleaseEvent(self, event):
        end = event.pos()

        if self.button == 0:
            if (
                not self.pixmapItem.pixmap().isNull()
                and self._path_item is not None
            ):
                self._path.lineTo(self.mapToScene(end))
                self._path.closeSubpath()
                self._path_item.setPath(self._path)
                self._path_item.setBrush(QBrush(QColor("red")))
                self._path_item.setFlag(
                    QGraphicsItem.ItemIsSelectable, True
                )
                self._path_item = None
            super(GraphicsView, self).mouseReleaseEvent(event)
        elif self.button == 1:
            rubberRect = self.rubberBand.geometry()
            viewRect = self.viewport().rect()
            sceneRect = self.mapToScene(rubberRect).boundingRect()#QRectF(self.pixmapItem.pixmap().rect())

            self.changeRubberBand = False
            self.rubberBand.hide() #if you would like for the selected region to go away after release

            width = self.imageScaled.width() / rubberRect.height()
            height = self.imageScaled.height() / rubberRect.height()

            self.imageScaled = self.image.scaled(width * self.imageScaled.width(), height * self.imageScaled.height(), QtCore.Qt.KeepAspectRatio)

            #center = [sceneRect.y() + (sceneRect.height() / 2), sceneRect.x() + (sceneRect.width() / 2)]
            #TODO - make it so the viewport is centered on the center of the selection region 
            #self.centerOn(center[1], center[0])
            self.pixmapItem.setPixmap(self.imageScaled)

            QGraphicsView.mouseReleaseEvent(self, event)


        elif self.button == 3:
            rubberRect = self.rubberBand.geometry()
            viewRect = self.viewport().rect()
            sceneRect = QRectF(self.pixmapItem.pixmap().rect())

            self.changeRubberBand = False
            self.rubberBand.hide() #if you would like for the selected region to go away after release

            self.editWindowtoRecip(rubberRect)
            QGraphicsView.mouseReleaseEvent(self, event)

    def editWindowtoRecip(self, rubberRect):
        editim = self.pixmapItem.pixmap().copy(rubberRect)
        self.w = editWindow(editim, self.cvogImage, rubberRect)
        self.w.setGeometry(500, 500, 300, 300)
        self.w.show()

没有错误,只是在我寻找的功能不太好。你知道吗


Tags: pathimageselfeventifdefbuttonfilename