Qt - заполнить круг изображениями

Я попытался заполнить круг четырьмя изображениями. Во-первых, каждая фотокисть имеет одинаковый размер, а затем масштабирует окончательное изображение с этим размером. Но результат не то, что я хочу.

На данный момент кружок на переднем плане и фотографии на заднем плане, как здесь:
введите здесь описание изображения
Как заполнить круг фотографиями и удалить прямоугольник?

Вот мой код:

QPixmap *CGlobalZone::profPicFromFourPics(QList<QPixmap> pixmapList)
{
        QPixmap *avatar = NULL;
        QImage roundedImage(CGlobalZone::AVATAR_WIDTH_M*2, CGlobalZone::AVATAR_HEIGHT_M*2, QImage::Format_ARGB32);
        roundedImage.fill(Qt::transparent);
        QBrush brush0(pixmapList[0]);
        QBrush brush1(pixmapList[1]);
        QBrush brush2(pixmapList[2]);
        QBrush brush3(pixmapList[3]);
        QPainter painter(&roundedImage);
        QPen pen(QColor(176, 216, 242), 1);
        painter.setRenderHint(QPainter::Antialiasing);
        painter.setBrush(brush0);
        painter.drawRect(0 , 0 , CGlobalZone::AVATAR_WIDTH_M  , CGlobalZone::AVATAR_HEIGHT_M  );
        painter.setBrush(brush1);
        painter.drawRect(CGlobalZone::AVATAR_WIDTH_M , 0 , CGlobalZone::AVATAR_WIDTH_M*2  , CGlobalZone::AVATAR_HEIGHT_M  );
        painter.setBrush(brush2);
        painter.drawRect(CGlobalZone::AVATAR_WIDTH_M , CGlobalZone::AVATAR_HEIGHT_M , CGlobalZone::AVATAR_WIDTH_M*2  , CGlobalZone::AVATAR_HEIGHT_M*2  );
        painter.setBrush(brush3);
        painter.drawRect(0 , CGlobalZone::AVATAR_HEIGHT_M , CGlobalZone::AVATAR_WIDTH_M*2  , CGlobalZone::AVATAR_HEIGHT_M*2  );
        painter.drawEllipse(0, 0, CGlobalZone::AVATAR_WIDTH_M*2-3 , CGlobalZone::AVATAR_HEIGHT_M*2-3 );
        avatar  = new QPixmap(QPixmap::fromImage(roundedImage).scaled(QSize(CGlobalZone::AVATAR_WIDTH_M, CGlobalZone::AVATAR_HEIGHT_M),
                                                    Qt::KeepAspectRatioByExpanding, Qt::SmoothTransformation));
       return avatar;
}

person Farzan Najipour    schedule 22.06.2015    source источник
comment
Как использовать QPixmap::setMask в этом вопросе? @Амартел   -  person Farzan Najipour    schedule 22.06.2015
comment
Вам нужно создать QBitmap, который содержит 1, где нужно рисовать и 0, где - нет. Для этого вы можете использовать Qt::color1 и Qt::color0. Поскольку QBitmap наследует QPixmap, вы можете нарисовать на нем круг, используя QPainter. Или вы можете загрузить его из файла.   -  person Amartel    schedule 22.06.2015


Ответы (2)


Я бы сделал это следующим образом (подробности в комментариях к исходному коду):

// The avatar image. Should be four, but use one for demonstration.
QPixmap source("avatar.png");

// Initialize the avatar and bring it to a standard size.
// This step may be skipped if avatars have the same sizes.
const int width = CGlobalZone::AVATAR_WIDTH_M;
const int height = CGlobalZone::AVATAR_HEIGHT_M;
source = source.scaled(width, height);

// Set up the final image that contains four avatar images.
QPixmap target(2 * width, 2 * height);
target.fill(Qt::transparent);

QPainter painter(&target);

// Set clipped region (circle) in the center of the target image
QRegion r(QRect(width / 2, height / 2, width, height), QRegion::Ellipse);
painter.setClipRegion(r);

painter.drawPixmap(0, 0, source);          // First avatar
painter.drawPixmap(width, 0, source);      // Second avatar
painter.drawPixmap(0, height, source);     // Third avatar
painter.drawPixmap(width, height, source); // Fourth avatar

target.save("test.png");
person vahancho    schedule 22.06.2015

Используйте пути рисования для задачи. Вместо того, чтобы рисовать эллипс, вы должны сделать

int dim = CGlobalZone::AVATAR_WIDTH_M*2;
QPainterPath entirePath;
QPainterPath ellipsePath;

entirePath.addRect(0, 0, dim, dim);
ellipsePath.addEllipse(0, 0, dim-3, dim-3);
QPainterPath outOfEllipse = entirePath.subtracted(ellipsePath);
painter.fillPath(outOfEllipse, QBrush(Qt::transparent));

Изменить: Поскольку QPainterPath предназначен для сложных случаев, вам следует использовать QRegion. После тестирования я обнаружил, что могут быть небольшие ошибки пикселей при заполнении внутри и снаружи одного и того же пути (в вашем случае все будет хорошо).

person UmNyobe    schedule 22.06.2015
comment
QRegion - плохая идея, это как хранить монохромную маску. Это никогда не будет хорошо выглядеть, кроме как для прямоугольных областей. - person Kuba hasn't forgotten Monica; 22.06.2015
comment
QRegion рендерил лучше для простой заливки внутри внешнего круга. Но опыта использования у меня мало. - person UmNyobe; 23.06.2015