【问题标题】:How to crop QPixmap that is set on a Scene with a rotated QGraphicsRectItem?如何裁剪在具有旋转 QGraphicsRectItem 的场景上设置的 QPixmap?
【发布时间】:2021-11-16 15:14:05
【问题描述】:

我不知道如何裁剪设置在场景中的 QPixmap,同时旋转的 QGraphicsRectItem 也放置在同一场景中。

这是我的 QGraphicsScene 和 QPixmap 的代码。

class crop_pattern(QGraphicsView):
    img_is_cropped = QtCore.Signal(object)
    def __init__(self, path, scale):
        super().__init__()
        # Connect graphics scene with graphics view
        self.setFixedSize(500, 500)
        self.scene = QGraphicsScene(self)
        self.setScene(self.scene)
        self.roi_scale = scale
      
        # Display image
        self.set_image(path)

    def set_image(self, path):
        pixmap = QtGui.QPixmap(path)

        if pixmap:
            pixmap = pixmap.scaledToHeight(self.roi_scale * pixmap.height())

        self.scene.clear()
        self.scene.addPixmap(pixmap)
        
        self.setAlignment(QtCore.Qt.AlignCenter)

    def wheelEvent(self, event):
        zoomInFactor = 1.05
        zoomOutFactor = 1 / zoomInFactor

        oldPos = self.mapToScene(event.pos())

        if event.angleDelta().y() > 0:
            zoomFactor = zoomInFactor
        else:
            zoomFactor = zoomOutFactor
            
        self.scale(zoomFactor, zoomFactor)

        newPos = self.mapToScene(event.pos())

        delta = newPos - oldPos
        self.translate(delta.x(), delta.y())

(感谢 QGraphicsView Zooming in and out under mouse position using mouse wheel 的 wheelEvent 函数)

这是用户点击某个按钮时生成的QGraphicsItem。

    QtCore.Slot(bool)
    def create_shape(self):
        sender = self.sender()
        if sender.text().lower() == "circle":
            self.shape = ellipse_shape(0, 0, 100, 100)

        elif sender.text().lower() == "rectangle":
            self.shape = rect_shape(0, 0, 100, 100)
            
        self.shape.setZValue(1)
        self.shape.setTransformOriginPoint(50, 50)

        self.crop_pattern.scene.addItem(self.shape) # added item to the same scene, which is crop_pattern.

这是问题所建议的 GUI。 (QGraphicsRectItem 已调整大小)

如何裁剪矩形内的像素?谢谢!

【问题讨论】:

    标签: python pyqt pyside qgraphicsview qgraphicsitem


    【解决方案1】:

    一种可能的解决方案是创建一个隐藏的 QGraphicsView 并使用render() 方法保存图像部分。隐藏 QGraphicsView 的目的不是修改现有视图,因为除了不受缩放影响之外,图像还必须旋转。

    from PyQt5 import QtCore, QtGui, QtWidgets
    
    
    def crop_rect(rect_item, scene):
        is_visible = rect_item.isVisible()
    
        rect_item.hide()
    
        hide_view = QtWidgets.QGraphicsView(scene)
        hide_view.rotate(-rect_item.rotation())
    
        polygon = rect_item.mapToScene(rect_item.rect())
        pixmap = QtGui.QPixmap(rect_item.rect().size().toSize())
        pixmap.fill(QtCore.Qt.transparent)
        source_rect = hide_view.mapFromScene(polygon).boundingRect()
    
        painter = QtGui.QPainter(pixmap)
        hide_view.render(
            painter,
            target=QtCore.QRectF(pixmap.rect()),
            source=source_rect,
        )
        painter.end()
    
        rect_item.setVisible(is_visible)
    
        return pixmap
    
    
    def main():
        app = QtWidgets.QApplication([])
    
        scene = QtWidgets.QGraphicsScene()
        view = QtWidgets.QGraphicsView(alignment=QtCore.Qt.AlignCenter)
        view.setScene(scene)
        # emulate wheel
        view.scale(0.8, 0.8)
    
        # create pixmap
        pixmap = QtGui.QPixmap(500, 500)
        pixmap.fill(QtGui.QColor("green"))
        painter = QtGui.QPainter(pixmap)
        painter.setBrush(QtGui.QColor("salmon"))
        painter.drawEllipse(pixmap.rect().adjusted(100, 90, -80, -100))
        painter.end()
    
        pixmap_item = scene.addPixmap(pixmap)
    
        rect = QtCore.QRectF(0, 0, 200, 300)
        rect_item = scene.addRect(rect)
        rect_item.setPen(QtGui.QPen(QtGui.QColor("red"), 4))
        rect_item.setPos(100, 100)
        rect_item.setTransformOriginPoint(50, 50)
        rect_item.setRotation(10)
    
        view.resize(640, 480)
        view.show()
    
        qpixmap = crop_rect(rect_item, scene)
        label = QtWidgets.QLabel()
        label.setPixmap(qpixmap)
        label.show()
    
        app.exec_()
    
    
    if __name__ == "__main__":
        main()
    

    输入:

    输出:

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-11-17
      • 2013-04-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-02-16
      • 1970-01-01
      • 2015-05-28
      相关资源
      最近更新 更多