Qml 中的那些坑(一)---Image 的内存

【写在前面】

        首先,要提一个版本bug。

        因为一个类似的bug是在Qt 5.13.0 中 ( 5.12 则没有),由 QQuickPaintedItem 引起的。

        详见:[QTBUG-78063] QQuickPaintedItem directly used, will grow infinite memory - Qt Bug Tracker

        同样的,使用 Image 后,也会无限增长内存

        但是先忽略这个bug,因为这里要讲的是 Image 的内存。


【正文开始】

        在 qml 中,Image 作为最常用的控件之一,简单又方便。

        然而,程序中大量使用 Image 后,我发现有些不对劲。

        例如,我使用一张高清的大图作为背景(2000 x 2000 background.jpg):

import QtQuick 2.12
import QtQuick.Window 2.12

Window {
    id: root
    visible: true
    width: 1024
    height: 680

    Image {
        anchors.fill: parent
        source: "background.jpg"
    }
}

        因为是JPG,它的压缩率很高,因此只占用 400KB 的空间。

        运行起来发现,内存占用 40MB (左右),看起来似乎可以接受。

        然而,接着多添加几张图片试试:

import QtQuick 2.12
import QtQuick.Window 2.12

Window {
    id: root
    visible: true
    width: 1024
    height: 680

    Image {
        anchors.fill: parent
        source: "background.jpg"
    }
    Image {
        anchors.fill: parent
        source: "background2.jpg"
    }
    Image {
        anchors.fill: parent
        source: "background3.jpg"
    }
}

        结果每多一张就增加 20MB,现在占用 80MB 内存了!

        这已经完全不能接受了好吗,虽然不可能每张图片都是 2000 x 2000,但也架不住图片多啊(ಥ _ ಥ)。

        于是我开始在文档中寻找答案  > > >

        最终,我找到了,那就是 sourceSize: size

此属性保存已加载图像的实际宽度和高度。

与缩放图像绘制的宽度和高度属性不同,此属性设置为加载的图像存储的实际像素数,以便大图像不会占用超过必要的内存。

        也就是说,该属性可以限制实际内存中图像的的大小。

        现在来试一下效果:

import QtQuick 2.12
import QtQuick.Window 2.12

Window {
    id: root
    visible: true
    width: 1024
    height: 680

    Image {
        anchors.fill: parent
        source: "background.jpg"
        sourceSize: Qt.size(1024, 680)
    }
}

        现在内存降到了 20MB。

        这样做的优点显而易见,那么缺点就是:

        在窗口 <= size(1024, 680) (初始大小)的时候,不会有任何区别,而在 > size(1024, 680) 时,会变模糊。

        具体原因是:放大失真后进行了平滑处理 ( 来源于 smooth 属性,默认 true,因此设为 false 将会出现明显锯齿 )。

        因此,我的建议是:将 sourceSize 设为一个合理的大小(并且最好稍微大一点)。


【结语】

        最后,讲一些题外话:

        Image 有一个属性 cache

Specifies whether the image should be cached. The default value is true.

Setting cache to false is useful when dealing with large images, to make sure that they aren't cached at the expense of small 'ui element' images.

翻译:

指定是否应缓存图像。 默认值是true。

在处理大图像时,将缓存设置为false非常有用,以确保它们不会以小的“ui元素”图像为代价进行缓存。

        开启 cache 后,在 Qml 内部, 会维护一个 QHash

        也就是说,同样 Image 只会加载一次,这样做明显是有好处的,那么文档中所说的,大图像设置为 false 的好处又是什么呢,是大图像不会被多次使用而省去了缓存的工作吗?

        这点暂时还在摸索中...

  • 3
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

梦起丶

您的鼓励和支持是我创作最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值