为啥当我使用 QImage::scaled() 时我的内存消耗很大?

Posted

技术标签:

【中文标题】为啥当我使用 QImage::scaled() 时我的内存消耗很大?【英文标题】:Why when I use QImage::scaled() I have a large memory expenditure?为什么当我使用 QImage::scaled() 时我的内存消耗很大? 【发布时间】:2016-01-22 11:29:26 【问题描述】:

我为教育目的编写了简单的图像查看器。并且应用程序必须能够缩放图像。为此,我使用 QImage::scaled()

void ScreenImage::zoomImage(const qreal zoomFactor)

    const qint32 src_width = m_Image.width();
    const qint32 src_height = m_Image.height();

    QImage img = m_Image.scaled(QSize(src_width, src_height) * zoomFactor,
                            Qt::IgnoreAspectRatio,Qt::FastTransformation);
    showImage(img);

之后我将收到的图片上传到 QLabel 并在屏幕上显示。

void ScreenImage::showImage(const QImage &img)

    _pLabel->setPixmap(QPixmap::fromImage(img));
    if(_pScrollArea->isHidden())
        _pScrollArea->show();

问题:为什么我在使用 QImage::scaled() 时内存消耗很大?我该如何解决?

我录制了video 以查看此问题。

感谢您的回答。

【问题讨论】:

【参考方案1】:

您应该改变实现缩放的方式。 因为您确实这样做了(通过缩放原始图像),所以缩放后的图像非常大并且消耗大量内存(每个像素至少 4 个字节)。

另外请注意,您只显示其中的一小部分,因此图像占用的大部分内存都是“未使用”的。

您需要做的不是缩放整个图像,而是仅缩放将显示给用户的部分。

我没有现成的解决方案,但您可以尝试自定义小部件和自定义绘画,它只会呈现图像的所需部分。

更新:

我刚刚想到的一些额外提示: 您可以准备自定义QWidget,它将其大小设置为缩放图像的大小并放入QScrollArea

然后在paintEvent 上,您可以使用来自QPaintEvent 的数据来确定已绘制(可见)的小部件区域。这将让您计算应提取和缩放原始图像的哪一部分以匹配小部件的可见区域。这个技巧将导致您将始终使用相同数量的内存,这将仅取决于您的窗口大小。

【讨论】:

非常感谢您的回答。感谢您的想法,我看到了 QImage::setDevicePixelRatio(),它可以满足我的需要。现在没有消耗的内存被浪费了。

以上是关于为啥当我使用 QImage::scaled() 时我的内存消耗很大?的主要内容,如果未能解决你的问题,请参考以下文章

当我使用 HTTP 协议尝试请求时,为啥会收到错误的请求响应?

为啥当我将 SKSpriteNode 与图像一起使用时它不会反弹,但当我使用 SKShapeNode 时它确实有效?

为啥当我使用 tkinter 配置选项时这个标签没有改变

当我对 args() 使用切入点时,为啥 tomcat 会抛出 NullPointErexception?

当我使用 set 作为捕获时,为啥 Twig 不能使用变量作为数组的索引?

当我在 plotly 中使用 ggplotly 函数时,为啥文本注释会丢失?