0

在QGraphicsScene中添加了QGraphicsPixmapItem。图像是通过setPhoto方法插入的。wheelEvent方法放大或缩小图像。

如果图像被缩放,我想将图像的显示部分作为 ROI(img[y:y+h,x:x+w]),QGraphicsPixmapItem(或其他)中是否有一些方法可以给我 x,y ,w,h 如果图像被缩放或者我必须在方法wheelEvent中计算它?

谢谢。

示例代码:

from PyQt5 import QtCore, QtWidgets, QtGui
from PyQt5.QtGui import QImage
from PyQt5.QtWidgets import *
import sys
import cv2
import os

class MainWindow(QMainWindow):

    def __init__(self, parent=None):
        QMainWindow.__init__(self, parent)

        self.setWindowTitle('ROI')
        self.setMinimumWidth(1400)
        self.setMinimumHeight(1000)
        self.main_widget = QtWidgets.QWidget(self)
        self.setCentralWidget(self.main_widget)

        self.view = GraphicsView(self)

        self.lay()
        self.akce()

    def lay(self):
        self.butt = QPushButton('Load image')
        self.hlay = QHBoxLayout(self.main_widget)
        self.grid = QGridLayout()
        self.hlay.addLayout(self.grid, 2)
        self.hlay.addWidget(self.view, 8)
        self.grid.addWidget(self.butt, 1, 1)

    def akce(self):
        self.butt.clicked.connect(self.loadImage)

    def loadImage(self):
        options = QFileDialog.Options()
        fileName, _ = QFileDialog.getOpenFileName(self, 'Load image', '',
                                                  'Images (*.bmp *.jpeg *.tif *.jpg *.png *.ppm *.xbm *.xpm)',
                                                  options=options)
        if fileName:
            flnm = r'{pth}'.format(pth=os.path.abspath(fileName))
            bgrImage = cv2.imread(fr'{flnm}')
            rgbImage = cv2.cvtColor(bgrImage, cv2.COLOR_BGR2RGB)
            rgbImage = QImage(rgbImage, rgbImage.shape[1], rgbImage.shape[0], rgbImage.strides[0], QImage.Format_RGB888)
            self.view.setPhoto(QtGui.QPixmap.fromImage(rgbImage))
            self.view.fitWindow()

class GraphicsView(QtWidgets.QGraphicsView):
    def __init__(self, parent):
        super(GraphicsView, self).__init__(parent)

        self.val_zoom = 0
        self.val_empty = True
        self._graphicsScene = QtWidgets.QGraphicsScene(self)
        self._mapaPixmap = QtWidgets.QGraphicsPixmapItem()
        self._graphicsScene.addItem(self._mapaPixmap)
        self.setScene(self._graphicsScene)
        self.setTransformationAnchor(QtWidgets.QGraphicsView.AnchorUnderMouse)
        self.setResizeAnchor(QtWidgets.QGraphicsView.AnchorUnderMouse)
        # self.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
        # self.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
        self.setBackgroundBrush(QtGui.QBrush(QtGui.QColor(30, 30, 30)))
        self.setFrameShape(QtWidgets.QFrame.NoFrame)

    def isLoaded(self):
        return not self.val_empty

    def fitWindow(self, scale=True):
        rect = QtCore.QRectF(self._mapaPixmap.pixmap().rect())
        if not rect.isNull():
            self.setSceneRect(rect)
            if self.isLoaded():
                unity = self.transform().mapRect(QtCore.QRectF(0, 0, 1, 1))
                self.scale(1 / unity.width(), 1 / unity.height())
                viewrect = self.viewport().rect()
                scenerect = self.transform().mapRect(rect)
                factor = min(viewrect.width() / scenerect.width(),
                             viewrect.height() / scenerect.height())
                self.scale(factor, factor)
            self.val_zoom = 0

    def setPhoto(self, pixmap=None):
        if pixmap and not pixmap.isNull():
            self.val_empty = False
            self.setDragMode(QtWidgets.QGraphicsView.ScrollHandDrag)
            self._mapaPixmap.setPixmap(pixmap)
        else:
            self.val_empty = True
            self.setDragMode(QtWidgets.QGraphicsView.NoDrag)
            self._mapaPixmap.setPixmap(QtGui.QPixmap())

    def wheelEvent(self, event):
        if self.isLoaded():
            if event.angleDelta().y() > 0:
                factor = 1.25
                self.val_zoom += 1
            else:
                factor = 0.8
                self.val_zoom -= 1
            if self.val_zoom > 0:
                self.scale(factor, factor)
            elif self.val_zoom == 0:
                self.fitWindow()
            else:
                self.val_zoom = 0

    def toggleDragMode(self):
        if self.dragMode() == QtWidgets.QGraphicsView.ScrollHandDrag:
            self.setDragMode(QtWidgets.QGraphicsView.NoDrag)
        elif not self._mapaPixmap.pixmap().isNull():
            self.setDragMode(QtWidgets.QGraphicsView.ScrollHandDrag)


if __name__ == '__main__':
    app = QApplication(sys.argv)
    wd = MainWindow()
    wd.show()
    sys.exit(app.exec_())

4

0 回答 0