矢量图像示例

Qt Quick 示例演示了 Qt SVGVectorImagesvgtoqml 的区别。

在 Qt 应用程序中包含二维矢量图形有几种不同的方法。本示例重点介绍SVG 格式以及如何在 Qt 中使用该格式。作为基准,Qt 支持SVG Tiny 1.2 配置文件的静态功能。此外 Qt SVG还可选择支持完整配置文件中的一些功能,但这些功能在本例中并未使用。

该示例显示了一个由 3x3 单元组成的网格,每个单元都包含相同的心脏矢量图像。心脏图像作为SVG 文件随示例一起提供。

在网格中,每一行都以不同的比例系数(分别为 1x、2.5x 和 4x)显示图像。

每列代表在 Qt 中呈现矢量图形的不同方式。最左边一列是Image 组件,中间一列是VectorImage 组件,最右边一列是使用svgtoqml工具创建的预生成QML 表示。

每种渲染矢量图形的方法都有自己的优点和缺点,并适合不同的使用情况。要做出使用哪种方法的明智决定,了解它们之间差异的细节会很有帮助。

Image 组件和 Qt SVG

当您使用Image 元素并将SVG 文件设为源文件时,将调用 Qt SVG.该插件将解析SVG 文件,使用QPainter 中的软件光栅化器对其进行光栅化,然后将其作为像素图图像提供给Qt Quick 。这相当于使用QSvgRenderer 类绘制图像。

        Image {
            sourceSize: Qt.size(topLevel.sourceSize, topLevel.sourceSize)
            source: "heart.svg"
        }

由于矢量图像是以特定尺寸栅格化的,因此我们对Image 应用的任何变换都将应用于栅格化图像。这可能会导致像素化伪影和不均匀的曲线。

通过Image 加载矢量图像时,最好按您打算显示的精确尺寸请求图像。当Image 以 1x 比例显示在最上面一行时,它看起来与其他图像完全相同,但比例系数越大,它看起来就越模糊。

如果图像只能以单一尺寸显示,那么这通常是性能最好的选择。按指定尺寸光栅化图像需要一定的启动成本,但之后将数据复制到屏幕上的成本就很低了。

但是,当图像被请求为多个不同尺寸时,启动成本就会增加,累积的内存消耗也会增加。在低端设备上以全帧率运行图像的动画缩放通常会变得过于昂贵。这些都是VectorImagesvgtoqml应考虑的用例。

VectorImage 组件

作为Image 的替代方案,Qt XML 提供了VectorImage 组件。该组件将SVG 图像转换为Qt Quick 中的矢量图形表示法,并在渲染到屏幕时按需在图形处理器上进行光栅化。

        VectorImage {
            width: topLevel.sourceSize
            height: topLevel.sourceSize
            preferredRendererType: VectorImage.CurveRenderer
            source: "heart.svg"
        }

由于图像没有预先栅格化,我们可以对其进行变换,而不会丢失对原始图形的保真度。请注意,该示例使用的是VectorImage.CurveRenderer 渲染器类型。建议在需要对图像进行变换和抗锯齿的情况下使用这种类型。

这意味着我们可以显示任意大小的图像,甚至可以对图像的比例进行动画处理,而所有工作都将由图形硬件完成。不过,当VectorImage 渲染到屏幕上时,其成本会比渲染Image 稍高。这是因为曲线的光栅化是在每次渲染组件时进行的,而不是提前进行。

因此,VectorImage 最适合尺寸经常变化的矢量图形。当图像的目标尺寸非常大,而内存消耗又是一个问题时,它也非常适合。使用Image 时,整个光栅化图像必须存储在图形内存中。因此,内存消耗将随着图像大小的增加而增加。无论渲染的目标大小如何,VectorImage 消耗的内存都是一样的。

svgtoqml工具

VectorImage 组件会解析SVG 文件,并在运行时建立一个由Qt Quick 项组成的等效场景。

如果SVG 是应用程序资产的一部分,那么可以使用svgtoqml工具提前完成部分工作。该工具生成的场景与VectorImage 相同,但不是在运行时构建,而是创建一个可包含在应用程序项目中的QML 文件。

在本例中,heart.svg 文件已预先转换为名为Heart.qml 的文件。它可以像其他Qt Quick 项目一样在场景中实例化。

        Heart {
            width: topLevel.sourceSize
            height: topLevel.sourceSize
        }

使用这种方法,我们就不必在每次启动应用程序时都解析SVG 文件。此外,svgtoqml 工具可以优化和分析形状,从而为渲染器提供提示,进一步加快其运行时处理速度。

在与VectorImage 相同的使用情况下,应考虑使用svgtoqml工具。当SVG 文件作为资产在应用程序构建时可用,而不是由应用程序的最终用户提供时,应优先使用svgtoqml工具。

示例项目 @ code.qt.io

© 2025 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.