QML图像平滑属性无效

16
在QML中,我创建了一个带有一组图像元素的Rectangle视图。我似乎无法让smooth属性起作用,这个属性已经在视图和图像上都设置为true。我尝试过缩放图像本身和缩放视图。无论我做什么,我都得到一个锯齿状的缩放图像。我错过了什么吗?
我正在使用Qt 5.2,并将QtQuick2ApplicationViewerQQuickView的子类)作为我的主视图。
我找到了一些解决方案,可以通过替换引擎中的图像处理程序来应用平滑处理,但我觉得smooth属性应该可以直接使用。
代码:
Image {
    source: "image_400x400.png"
    width:  400
    height: 400
    smooth: true

    transform {
        Scale {xScale: 0.25; yScale: 0.25}
    }
}

第二次尝试:

Image {
    source: "image_400x400.png"
    width:  100
    height: 100
    smooth: true
}

第三次尝试:

Rectangle {
    width:  400
    height: 400
    smooth: true

    Image {
        source: "image_400x400.png"
        width:  400
        height: 400
        smooth: true
    }

    transform {
        Scale {xScale: 0.25; yScale: 0.25}
    }
}

每次我都得到相同的结果。

更新:如Nejat建议,我尝试了新的Qt 5 antialiasing属性。结果确实有所改善,但当缩放到0.5倍以下时,边缘仍然有些锯齿状。是否有办法改变抗锯齿质量?

从左到右:

  • 预期输出(使用Photoshop缩放,未编辑)
  • 启用antialiasingsmooth
  • 仅启用smooth

三个带缩放级别的抗锯齿结果

我还在想为什么smooth没有起作用。

3个回答

20

想要实现平滑的降采样,你需要使用mipmaps

在即将发布的Qt 5.3版本中,以下操作可以实现这一功能:

Image {
    source: "image_400x400.png"
    width: 100
    height: 100
    mipmap: true
}

对于Qt 5.2,你可以尝试以下作为高质量替代你多重采样方法的方案:

ShaderEffectSource {
    id: src
    sourceItem: Image { source: "image_400x400.png" }
    mipmap: true
}

ShaderEffect {
    width: 100
    height: 100
    property var source: src
}

如果你不需要动态更改图像的比例,那么最优的方法是使用以下代码(对于所有相关的 Qt 版本):

Image {
    source: "image_400x400.png"
    sourceSize.width: 100
    sourceSize.height: 100
}

图片将在CPU上进行高质量降采样,然后上传到GPU。需要注意的是,由于图像信息丢失,当以原始图像比例显示时,它会变得更加模糊。

关于smooth属性:

Imagesmooth属性启用线性插值。它默认开启,并且是对最近邻插值的改进,当 smooth=false时使用;但是对于缩小操作帮助不大。

关于antialising属性:

设置antialiasing=true 不会改变图像缩放的质量。它只是平滑边缘,在旋转图像时可能很重要。


这真的很详细,谢谢Kay!我现在正在尝试它 - 它可以工作,但是开箱即用的结果有太多的混叠,当我将图像缩小超过4倍时会变得模糊。我猜编写自定义着色器效果是下一步?也许我只需坚持之前发布的表面格式解决方案,以保持简单。 - Robbert
再次感谢Kay,确实在Qt 5.3中mipmap:true解决了这个问题。 - Robbert
谢谢!我浪费了15分钟时间调整“antialias”属性,纳闷为什么它没起作用… - Kyle Strand

2
您应该将“antialiasing”属性设置为true。它可以在任何项目上进行设置,包括画布。根据文档:

主要用于矩形和基于图像的元素,以决定该项是否应使用抗锯齿。启用抗锯齿的项目需要更多的内存,并且渲染速度可能会变慢。

默认值为false

因此,它可以像这样:

Image {
    source: "image_400x400.png"
    width:  100
    height: 100
    smooth: true
    antialiasing: true
}

谢谢Nejat!似乎antialiasing是Qt 5中的一个新属性。它确实改善了渲染效果,但结果仍然有些锯齿状。 - Robbert
我已经根据您的建议更新了我的答案。我仍然觉得smooth属性应该有所不同(它仍然没有任何作用),而且我应该能够以某种方式设置抗锯齿质量。有什么想法吗? - Robbert
为了在拉伸图像时使其看起来更好,我建议您使用SVG图像而不是PNG图像。 - Nejat
使用SVG图像似乎没有什么区别。SVG似乎是预采样的,因此当我缩放图像时,同样低质量的抗锯齿效果仍然可见。 - Robbert
SVG 图像是矢量图。与 PNG 等光栅图像不同,矢量图在缩放过程中不会失去质量。我认为问题出在其他地方。 - Nejat

2

更新:自Qt 5.3起,mipmap属性解决了这个问题。下面的回答仅适用于Qt 5.2或更早版本。

添加antialiasing属性(自Qt 5开始)可以实现你期望的smooth属性效果。感谢Nejat。然而,如更新的问题所述,抗锯齿质量仍然很差。为了解决这个问题,定义一个自定义表面格式来设置自定义抗锯齿采样率(摘自main.cpp):

QtQuick2ApplicationViewer view;

QSurfaceFormat format;
format.setSamples(16);
view.setFormat(format);

请参考文档:QSurfaceFormat::setSamples
许多人建议使用SVG代替PNG。根据我的经验,至少在默认的Qt Quick设置下,SVG在特定大小被采样,因此与PNG完全相同。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接