-1

I am making a simple editor where the user can click on points of an image and crop out a shape. My implementation is terribly inefficient and as I'm new to qt, I have trouble deciphering all the functions on qt's docs.

    QPolygonF polygon(points);
    std::map<std::string, int> map = pointsHandler.getOutsideVals();
    for(int i = map["Left"]; i < map["Right"]; i++){
        for(int j = map["Top"]; j < map["Bottom"]; j++){
            for(int n = 0; n < points.size(); n++){
                if(polygon.containsPoint(QPointF(i,j), Qt::OddEvenFill)){
                    image.setPixelColor(QPoint(i - xOffset, j - yOffset), Qt::transparent);
                }
            }
        }
    }
    painter.drawImage(xOffset,yOffset, image);

Currently how I'm doing it is looping through a rectangle given by the outer most points of the polygon. If a point is in the polygon or not I change the pixel value to be transparent. The polygon is made from the users clicked points which I then store the outer most values in a map. When I crop out large portions, it takes far to long and was I looking for some advice to make this more efficient. Thank you.

EDIT I am now using setClipPath mentioned by G.M. and have no performance issues, however the way I found to get the job done now seems like a waste of memory. Using setClipPath(...) the best work around I found was to make multiple Qt class objects on the stack, it works great just seems like I'm working around to much stuff. Here's the updated code.

    QPolygon clipPolygon = QPolygonF(points).toPolygon();
    QRegion clippedRegion(clipPolygon, Qt::OddEvenFill);
    QRect translatedImageRect = image.rect().translated(QPoint(xOffset, yOffset));
    QRegion unClippedRegion = QRegion(translatedImageRect).subtracted(clippedRegion);
    painter.save();
    painter.setClipRegion(unClippedRegion, Qt::ReplaceClip);
    painter.drawImage(xOffset, yOffset, image);
    painter.restore();

It works great, just feel like I'm wasting memory.

symanoz
  • 51
  • 4
  • 1
    Please inspect documentation. You are doing that in worst possible way since you didn't read documentation. – Marek R Dec 14 '22 at 20:46
  • 2
    Paint the original image onto a new image using the polygon shape as a clip path. – G.M. Dec 14 '22 at 20:50

1 Answers1

1

You can use QPainter to make a rectangle of your image transparent.

QImage image("/home/tim/Bilder/Example.png");

QPainter painter(&image);
painter.setCompositionMode(QPainter::CompositionMode_Source);
painter.fillRect(0, 0, 10, 10, Qt::transparent);
painter.end();
image.save("/home/tim/Bilder/changed.png", "PNG");

Before After

Tim
  • 406
  • 3
  • 14