我正在尝试将来自各种来源的基于PyQt5的图像查看器Python代码拼凑在一起,并将功能扩展到在加载的图像内裁剪感兴趣的区域(ROI)。问题在于,在确定像素位置时,映射的坐标和鼠标单击会考虑滚动条和菜单条。以下是加载图像并提供边框功能的代码,但是由于偏移,我似乎无法准确绘制/裁剪框。
Mono<Object>
答案 0 :(得分:0)
在这些情况下,QRubberBand最好是QLabel的儿子,因此不需要进行很多转换。
另一方面,事件的坐标与窗口有关,因此我们必须将其转换为QLabel的坐标。为此,一种简单的方法是将相对于窗口的局部坐标转换为全局坐标,然后将相对于QLabel的全局坐标转换为局部坐标。
最后,在缩放图像时,由于currentQRect相对于缩放后的QLabel相对,但内部QPixmap尚未缩放,因此会影响坐标。
def mousePressEvent (self, event):
self.originQPoint = self.imageLabel.mapFromGlobal(self.mapToGlobal(event.pos()))
self.currentQRubberBand = QtWidgets.QRubberBand(QtWidgets.QRubberBand.Rectangle, self.imageLabel)
self.currentQRubberBand.setGeometry(QtCore.QRect(self.originQPoint, QtCore.QSize()))
self.currentQRubberBand.show()
def mouseMoveEvent (self, event):
p = self.imageLabel.mapFromGlobal(self.mapToGlobal(event.pos()))
QtWidgets.QToolTip.showText(event.pos() , "X: {} Y: {}".format(p.x(), p.y()), self)
if self.currentQRubberBand.isVisible() and self.imageLabel.pixmap() is not None:
self.currentQRubberBand.setGeometry(QtCore.QRect(self.originQPoint, p).normalized() & self.imageLabel.rect())
def mouseReleaseEvent (self, event):
self.currentQRubberBand.hide()
currentQRect = self.currentQRubberBand.geometry()
self.currentQRubberBand.deleteLater()
if self.imageLabel.pixmap() is not None:
tr = QtGui.QTransform()
if self.fitToWindowAct.isChecked():
tr.scale(self.imageLabel.pixmap().width()/self.scrollArea.width(),
self.imageLabel.pixmap().height()/self.scrollArea.height())
else:
tr.scale(1/self.scaleFactor, 1/self.scaleFactor)
r = tr.mapRect(currentQRect)
cropQPixmap = self.imageLabel.pixmap().copy(r)
cropQPixmap.save('output.png')