回答此问题可获得 20 贡献值,回答如果被采纳可获得 50 分。
<p>在PyQt5中有没有一些简单的方法来获取QLabel中显示的pixmap的真实维度?我试着用橡皮筋选择图像的一部分。但我找不到一个方法来限制橡皮筋只限于pixmap。这个QLabel.pixmap标签().rect()返回整个QLabel的维度,而不仅仅是pixmap。当pixmap被缩放并且图片的侧面有条纹时,问题就出现了。在</p>
<p>示例图像</p>
<p><img src="https://i.stack.imgur.com/Q6SRb.jpg" alt=""/></p>
<p>示例图像2</p>
<p><img src="https://i.stack.imgur.com/dkZqD.jpg" alt=""/></p>
<p>我贴的都是不言而喻的。我不想让橡皮筋从照片中移到白色条纹上。在</p>
<pre><code>class ResizableRubberBand(QWidget):
def __init__(self, parent=None):
super(ResizableRubberBand, self).__init__(parent)
self.aspect_ratio = None
self.setWindowFlags(Qt.SubWindow)
self.layout = QHBoxLayout(self)
self.layout.setContentsMargins(0, 0, 0, 0)
self.grip1 = QSizeGrip(self)
self.grip2 = QSizeGrip(self)
self.layout.addWidget(self.grip1, 0, Qt.AlignLeft | Qt.AlignTop)
self.layout.addWidget(self.grip2, 0, Qt.AlignRight | Qt.AlignBottom)
self.rubberband = QRubberBand(QRubberBand.Rectangle, self)
self.rubberband.setStyle(QStyleFactory.create("Fusion"))
self.rubberband.move(0, 0)
self.rubberband.show()
self.show()
class ResizablePixmap(QLabel):
def __init__(self, bytes_image):
QLabel.__init__(self)
self.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Ignored)
self.setAlignment(Qt.AlignVCenter | Qt.AlignHCenter)
self.setStyleSheet("background-color:#ffffff;")
self.update_pixmap(bytes_image)
def resizeEvent(self, event):
if event:
x = event.size().width()
y = event.size().height()
else:
x = self.width()
y = self.height()
self.current_pixmap = self._bytes2pixmap(self.bytes_image_edit)
self.setPixmap(self.current_pixmap.scaled(x, y, Qt.KeepAspectRatio))
self.resize(x, y)
def update_pixmap(self, bytes_image):
self.bytes_image_edit = bytes_image
self.current_pixmap = self._bytes2pixmap(bytes_image)
self.setPixmap(self.current_pixmap)
self.resizeEvent(None)
@staticmethod
def _bytes2pixmap(raw_image):
image = QImage()
image.loadFromData(raw_image)
return QPixmap(image)
@staticmethod
def _pixmap2bytes(pixmap):
byte_array = QByteArray()
buffer = QBuffer(byte_array)
buffer.open(QIODevice.WriteOnly)
pixmap.save(buffer, 'PNG')
return byte_array.data()
@property
def image_dims(self):
return self.width(), self.height()
def force_resize(self, qsize):
self.resizeEvent(QResizeEvent(qsize, qsize))
class SelectablePixmap(ResizablePixmap):
def __init__(self, bytes_image):
super().__init__(bytes_image)
self.currentQRubberBand = None
self.move_rubber_band = False
self.rubber_band_offset = None
def cancel_selection(self):
self.currentQRubberBand.hide()
self.currentQRubberBand.deleteLater()
self.currentQRubberBand = None
self.selectionActive.emit(False)
def mousePressEvent(self, eventQMouseEvent):
if not self.currentQRubberBand:
self.currentQRubberBand = ResizableRubberBand(self)
self.selectionActive.emit(True)
if self.currentQRubberBand.geometry().contains(eventQMouseEvent.pos()):
self.move_rubber_band = True
self.rubber_band_offset = (eventQMouseEvent.pos() -
self.currentQRubberBand.pos())
else:
self.originQPoint = eventQMouseEvent.pos()
if self.pixmap().rect().contains(self.originQPoint):
self.currentQRubberBand.setGeometry(QRect(self.originQPoint,
QSize()))
self.currentQRubberBand.show()
def mouseMoveEvent(self, eventQMouseEvent):
if self.move_rubber_band:
pos = eventQMouseEvent.pos() - self.rubber_band_offset
if self.pixmap().rect().contains(pos):
self.currentQRubberBand.move(pos)
else:
rect = QRect(self.originQPoint, eventQMouseEvent.pos())
self.currentQRubberBand.setGeometry(rect.normalized())
def mouseReleaseEvent(self, eventQMouseEvent):
if self.move_rubber_band:
self.move_rubber_band = False
</code></pre>