在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_())