> 文章列表 > qml Image 内存问题

qml Image 内存问题

qml Image 内存问题

背景

笔者在项目中,有一个历史记录的功能,历史记录是类似一个相册的功能,当进入次功能的时候发现内存占用特别大,所以研究下 Image

在 qml 中,Image 作为最常用的控件之一,简单又方便。然而,程序中大量使用 Image 后,我发现有些不对劲。

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

import QtQuick 2.12
import QtQuick.Window 2.12Window {id: rootvisible: truewidth: 1024height: 680Image {anchors.fill: parentsource: "background.jpg"}
}

因为是JPG,它的压缩率很高,因此只占用 400KB 的空间。运行起来发现,内存占用 40MB (左右),看起来似乎可以接受。然而,接着多添加几张图片试试:

import QtQuick 2.12
import QtQuick.Window 2.12Window {id: rootvisible: truewidth: 1024height: 680Image {anchors.fill: parentsource: "background.jpg"}Image {anchors.fill: parentsource: "background2.jpg"}Image {anchors.fill: parentsource: "background3.jpg"}
}

结果每多一张就增加 20MB,现在占用 80MB 内存了!这已经完全不能接受了好吗,虽然不可能每张图片都是 2000 x 2000,但也架不住图片多啊(ಥ _ ಥ)。

于是我开始在文档中寻找答案 > > >最终,我找到了,那就是 sourceSize: size,此属性保存已加载图像的实际宽度和高度。

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

现在来试一下效果:

import QtQuick 2.12
import QtQuick.Window 2.12Window {id: rootvisible: truewidth: 1024height: 680Image {anchors.fill: parentsource: "background.jpg"sourceSize: Qt.size(1024, 680)}
}

现在内存降到了 20MB。
这样做的优点显而易见,那么缺点就是:
在窗口 <= size(1024, 680) (初始大小)的时候,不会有任何区别,而在 > size(1024, 680) 时,会变模糊。
具体原因是:放大失真后进行了平滑处理 ( 来源于 smooth 属性,默认 true,因此设为 false 将会出现明显锯齿 )。
因此,我的建议是:将 sourceSize 设为一个合理的大小(并且最好稍微大一点)。

解决方案

设置了 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 设置成false,不然内存会消耗的非常大