【问题标题】:Qt- fill circle with imagesQt-用图像填充圆圈
【发布时间】:2015-06-22 12:52:37
【问题描述】:

我尝试用四张图片填充圆圈。首先,每个照片刷都具有相同的大小,然后以该大小缩放最终图像。但结果不是我想要的。

现在前景是圆圈,背景是照片,比如这里:

如何用照片填充圆圈并删除矩形?

这是我的代码:

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;
}

【问题讨论】:

  • QPixmap::setMask ?
  • 如何在这个问题上使用 QPixmap::setMask? @Amartel
  • 您需要创建QBitmap,其中包含您要绘制的10,其中-不是。您可以为此使用Qt::color1Qt::color0。因为QBitmap继承了QPixmap,你可以在上面画一个圆,使用QPainter。或者你可以从文件中加载它。

标签: c++ qt qpainter


【解决方案1】:

我会通过以下方式执行此操作(源 cmets 中的详细信息):

// 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");

【讨论】:

    【解决方案2】:

    为任务使用painter paths。而不是 drawEllipse 你应该这样做

    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。经过测试,我发现在同一路径的内部和外部填充时可能会出现小像素错误(在您的情况下会很好)。

    【讨论】:

    • QRegion 是个坏主意,就像存储单色蒙版一样。除了矩形区域外,它永远不会看起来很好。
    • QRegion 对于简单的内外圆填充确实渲染得更好。但我没有太多使用它的经验。
    猜你喜欢
    • 1970-01-01
    • 2011-05-15
    • 1970-01-01
    • 2019-01-02
    • 2019-01-24
    • 1970-01-01
    • 2020-09-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多