I am creating a simple application with PyQt6. I want to my code to automatically crop the selected image into circle shape. How can I do that? Please help
-
Why you don't let the PyQt app select the image file and then crop it with [Pillow](https://pypi.org/project/Pillow/) and then display the image again in the app? – raspiduino Mar 14 '21 at 15:13
-
Can Pillow library do that? – Mar 14 '21 at 15:30
-
Yeb, see [this](https://note.nkmk.me/en/python-pillow-square-circle-thumbnail/) post. – raspiduino Mar 14 '21 at 15:37
1 Answers
Using an external library like pillow or opencv makes things easy as they generally have functions that already provide similar processing, but there's no need to add a dependency for simple manipulations like this, unless performance becomes an issue.
On Qt it's pretty straightforward: create a new QPixmap based on the minimum extent (assuming the circle is going to be the biggest possible in a given rectangle), create a QPainterPath with a circle that will be used for clipping, and finally draw the source contents in it.
def circleImage(imagePath):
source = QtGui.QPixmap(imagePath)
size = min(source.width(), source.height())
target = QtGui.QPixmap(size, size)
target.fill(QtCore.Qt.transparent)
qp = QtGui.QPainter(target)
qp.setRenderHints(qp.Antialiasing)
path = QtGui.QPainterPath()
path.addEllipse(0, 0, size, size)
qp.setClipPath(path)
sourceRect = QtCore.QRect(0, 0, size, size)
sourceRect.moveCenter(source.rect().center())
qp.drawPixmap(target.rect(), source, sourceRect)
qp.end()
return target
This obviously creates an image with transparent background around the circle, you can use any of the global colors or your own QColor.
Note that, no matter the color, the fill()
is mandatory, otherwise there will probably be random pixels on the unpainted portions of the image instead (usually some "RAM residue").

- 41,230
- 6
- 33
- 58