Search code examples
pythonmathpyqtborderqimage

PyQt QImage Border Radius with for loop


I have Rectangle PNG, i want to process this image, remove some pixels to margin and save it in png format.

Here what i want at end;

Added margin

Normal Image (There is no margin - border radius):

Normal PNG

Here is my code; i tried somethings but not working properly;

qimg = QImage(PNG_YOL)
qimg = qimg.convertToFormat(QImage.Format_ARGB32) # making png or will be there black pixels
p = QPainter()
p.begin(qimg)
w = qimg.width() - 1
h=qimg.height() -1
for x in range(int(maxx)):
    dx = 1 # i changed this value to get what i want, it works but not very fine, i am looking better way
    for y in range(int(maxy)):
        if x == 0:
            qimg.setPixel(x, y, Qt.transparent)
            qimg.setPixel(w - x, y, Qt.transparent)
        if x != 0 and y < int(h * 1 / x / dx):
            qimg.setPixel(x, y, Qt.transparent)
            qimg.setPixel(w - x, y, Qt.transparent)
        if x != 0:
            qimg.setPixel(x, int(h * 1 / x / dx), Qt.transparent)
            qimg.setPixel(w - x, int(h * 1 / x / dx), Qt.transparent)

p.end()
qimg.save(PNG_YOL)

With this code, i can get fine result but i am looking for better way.

Note: I just want only add margins to left-top and right-top.


Solution

  • Instead of getting too involved in processing pixel by pixel you can use QPainter with a QPainterPath:

    from PyQt5 import QtCore, QtGui
    
    
    qin = QtGui.QImage("input.png")
    
    qout = QtGui.QImage(qin.size(), qin.format())
    qout.fill(QtCore.Qt.transparent)
    painter = QtGui.QPainter(qout)
    path = QtGui.QPainterPath()
    
    radius = 20
    r = qout.rect()
    path.arcMoveTo(0, 0, radius, radius, 180)
    path.arcTo(0, 0, radius, radius, 180, -90)
    path.arcTo(r.width()-radius, 0, radius, radius, 90, -90)
    path.lineTo(r.bottomRight())
    path.lineTo(r.bottomLeft())
    path.closeSubpath()
    
    painter.setClipPath(path)
    painter.drawImage(QtCore.QPoint(0, 0), qin)
    painter.end()
    
    qout.save("output.png")