pyqt5qpixmapresize-image

Changing the size of a Qpixmap


how i can change the size/shape of Qpixmap to receive a result like this?

original

Result


Solution

  • QTransform can create basic shape transformations, which can then be applied to QPixmap.transformed().

    This specific case uses a "perspective" transformation, which uses projection and scaling information, and it's achieved using QTransform.quadToQuad(). Note that QTransform also provides squareToQuad(), but it's sometimes unreliable.

    The important thing is to create two QPolygonF instances, with the first based on the rectangle of the image, and the second with those corners at their "projected" points.

    Note that creating a QPolygonF from a rectangle results in a polygon with 5 points, with the last one being the first in order to make it "closed". The QTransform quadToQuad, instead, requires a 4 points, so you have to remove the last point. Also note that the corners must be in the same order, so they will be: top left, top right, bottom right, bottom left.

    In the following example, the perspective moves the top right corner at 20% of the height and the bottom right at the same opposite point (height - 80% of height).

    class ProjectionTest(QtWidgets.QWidget):
        def __init__(self):
            super().__init__()
            layout = QtWidgets.QVBoxLayout(self)
            source = QtGui.QPixmap('square.jpg')
            layout.addWidget(QtWidgets.QLabel(pixmap=source))
    
            # the original rectangle of the image, as a QRectF (floating point)
            rect = QtCore.QRectF(source.rect())
            # the source polygon, ignoring the last point
            square = QtGui.QPolygonF(rect)[:4]
            # the "projected" square
            cone = QtGui.QPolygonF([
                rect.topLeft(), 
                QtCore.QPointF(rect.right(), rect.height() * .2), 
                QtCore.QPointF(rect.right(), rect.height() * .8), 
                rect.bottomLeft(), 
            ])
            transform = QtGui.QTransform()
            if QtGui.QTransform.quadToQuad(square, cone, transform):
                new = source.transformed(transform, QtCore.Qt.SmoothTransformation)
                layout.addWidget(QtWidgets.QLabel(pixmap=new))
    

    And this is the final result:

    Result of the above code