Qt:为什么QGraphicsView设置Antialiasing/SmoothPixmapTransform没生效?

28 篇文章 4 订阅

QGraphicsView::setRenderHint有两个常用的选项:QPainter::AntialiasingQPainter::SmoothPixmapTransform,前者是用来打开反走样功能,后者用来在对图片进行缩放时启用线性插值算法而不是最邻近算法。然而这两个选项都有一些坑,想达到预期的效果的话得做一些额外的功课。

QPainter::Antialiasing和QOpenGLWidget

如果viewport被设置成了QOpenGLWidget控件的话,想要启用QPainter::Antialiasing,那QOpenGLWidget必须开启多重采样,否则反走样效果完全不生效。毕竟OpenGL默认的反走样手段就是多重采样(是否也是唯一的手段呢?),没开多重采样就没反走样很正常。不过这种情况下Qt连个警告提示都不会给,这就有点坑了。不过这个坑在Qt文档Graphics View Framework里有提到,那就怪自己没好好读文档吧。
如果viewport被设置成QWidget控件的话就没这个问题了,用CPU反走样有内存就可以了。

QPainter::SmoothPixmapTransform和QGraphicsPixmapItem

(这个比上面那个要坑。)如果没有特别的需求,往场景里面添加图片用QGraphicsScene::addPixmap就可以,这个方法会创建一个QGraphicsPixmapItem,然后添加到场景里面。

当我们放大场景时,已添加的图片也会跟着放大,这就涉及到一个问题:使用哪种插值算法进行放大?默认情况下使用的是最邻近算法,放大后会有马赛克效果。如果我们希望线性插值算法来使图像平滑一些,该怎么做呢?QGraphicsView的文档里面提到了QPainter::SmoothPixmapTransform,能够改变默认的插值算法。然而实际情况是,如果使用QGraphicsScene::addPixmap这种方式插入图片的话,这个选项是无效的!因为QGraphicsPixmapItem有另外一个属性transformationModeQGraphicsPixmapItem放大时的插值算法由这个属性决定,完全不受QPainter::SmoothPixmapTransform的影响。QGraphicsPixmapItem::paint是这么实现的:

void QGraphicsPixmapItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
                                QWidget *widget)
{
    Q_D(QGraphicsPixmapItem);
    Q_UNUSED(widget);

    painter->setRenderHint(QPainter::SmoothPixmapTransform,
                           (d->transformationMode == Qt::SmoothTransformation));

    painter->drawPixmap(d->offset, d->pixmap);

    if (option->state & QStyle::State_Selected)
        qt_graphicsItem_highlightSelected(this, painter, option);
}

不管传入的painterrenderHint是什么,都会被覆盖掉。那这样的话QPainter::SmoothPixmapTransform就形同虚设了,除非自己实现一个管理图片的QGraphicsItem类。

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值