本页内容

矢量图像示例

一个Qt Quick 示例,展示了 Qt SVG、VectorImage 和svgtoqml 之间的区别。

3×3 网格,用于比较不同比例下 Image、VectorImage 和 svgtoqml 对心形图案的渲染效果

您可以在 Qt 应用程序中通过多种不同方式嵌入二维矢量图形。本示例重点介绍SVG 格式及其在 Qt 中的应用。作为基准,Qt 支持“SVG Tiny 1.2 ”配置文件的静态功能。此外, Qt SVG 可选地支持完整配置文件中的某些功能,但本示例中未使用这些功能。

本示例展示了一个由 3×3 个单元格组成的网格,每个单元格都包含同一张心形矢量图像。该心形图像以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 以1倍缩放比例显示在最顶行时,其外观与其他图像完全一致,但在更高缩放比例下,图像会开始显得模糊。

如果图像始终仅以单一尺寸显示,那么这通常是性能最佳的选择。虽然将图像栅格化为指定尺寸会产生初始化开销,但此后将数据复制到屏幕上的开销非常低。

但随着图像被请求以多种不同尺寸显示,初始化开销会逐渐增加,累积的内存占用也会随之增长。在低端设备上,图像的动画缩放效果往往会过于耗资源,难以在全帧率下运行。对于此类用例,应考虑使用VectorImage 和svgtoqml。

VectorImage 组件

作为Image 的替代方案,Qt 提供了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_target_qml_from_svg(vectorimageexample
    CURVE_RENDERER
    OPTIMIZE_PATHS
    FILES heart.svg
    OUTPUTS Heart.qml
    COPYRIGHT_STATEMENT
        "Copyright © 2024 The Qt Company Ltd.\\nSPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause"
)

该组件可以像其他任何Qt Quick 项目一样在场景中实例化。

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

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

svgtoqml工具应适用于与VectorImage 相同的使用场景,并且当SVG 文件在应用程序构建时作为资源提供(而非由应用程序的最终用户提供)时,应优先使用该工具。

示例项目 @ code.qt.io

© 2026 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.