1
votes

My Qt Quick application is slowing down and consuming way too much memory when I load Images. I am loading around 5 PNG images that are large, about 50MB each.

See the size here:

enter image description here

Before loading the Images the memory consumption of the app is about 300MB, not too bad...Then when I load the 5 Images it jumps to 4.4 GB and stays there! ( I tried calling gc() on completed, it did nothing)

So I did some experiments. I wrote this basic application, just a QML Image. I executed without an image source, and the memory was 28.7 MB

import QtQuick 2.12
import QtQuick.Controls 2.3

Image {
    id: imageId
    anchors.fill: parent
    fillMode: Image.PreserveAspectFit
    anchors.centerIn: parent
    //source: 'test_images/1.png'
}

This is a screen capture from Mac's 'Activity Monitor'

enter image description here

When I added the 50MB image as the source the memory consumption jumped to 1.39GB and stayed there! Even after gc() which did nothing...

import QtQuick 2.12
import QtQuick.Controls 2.3

Image {
    id: imageId
    anchors.fill: parent
    fillMode: Image.PreserveAspectFit
    anchors.centerIn: parent
    source: 'test_images/1.png'
}

Another screen capture from 'Activity Monitor'

enter image description here

What is happening to this Image object to make it consume 1.39GB of memory! The image is only 50MB! This is the root of my problems with my app and it is making my application almost unusable. This is a major problem for the QtQuick platform.

Any comments or suggestions on how to resolve this? Thanks! I am using Qt 5.12

2
What is the size in pixel of the image? - Benjamin T
As for me I've never seen so terrible consumption on Windows and Linux. Usually it takes maybe 200% of the images sizes, ok cache etc. Unfortunately I can't test it in Mac. Anyway, if you want to just show images I mean no effects etc, you can write your custom Item which just paint image on the canvas and nothing else. - folibis
@BenjaminT The size in pixels is 11,000 x 11,000 - Edwin Fernandez

2 Answers

4
votes

The PNG file size is not relevant to the RAM usage at runtime. Images stored as PNG are compressed and therefore can have a very low size.

When you load and display a PNG image in a program, the image is decompressed and much more memory is used.

Typically for an image with 4 channels (RGBA) with 8 bits per channel, the memory footprint will be:

memory = 1 byte * 4 channels * width * height
  • For a 1920x1080 image it will give 8,100 KiB.
  • For a 4K image: 32,400 KiB
  • For an 11,000x11,000 image: 462 MiB

So a consumption of a few GB of RAM for a program loading multiple 11,000x11,000 images is not surprising.

Still the reported consumption of 1.39 GB is a bit surprising for a single image. But there are several possible explanations:

  • Qt (and OpenGL) needs to make and store copy of the image.
  • Your PNG uses more than 8 bits per channels. I think that PNG can go up to 16 bits per channel. If it is your case it will double the RAM consumption.
  • The image storage has memory overhead for big images, leading to increase memory consumption.
  • There is a bug somewhere...

There are possible solutions for reducing the memory footprint, but I think they all requires to reduce the image size. Given that most screens are 4K or less, you never need to display all the image pixels at a given time. So what you could do is crop or resize the image to what you exactly need. This can be done statically (i.e you do it yourself before compiling), or dynamically at runtime: you load the image, compute the reduced image and unload the original image.

0
votes

you can try this QML Image properties to try to resize image

 sourceSize.height:height
 sourceSize.width: width

https://doc.qt.io/qt-5/qml-qtquick-image.html#sourceSize-prop