在Qt中设置pixmap时的执行时间很奇怪

Weird execution times when setting pixmap in Qt

本文关键字:执行时间 Qt 设置 pixmap      更新时间:2023-10-16

看看下面的代码,图像QImage类型的类成员。

void ImageViewer::setImage(const QImage &newImage)
{
Image = newImage; // takes 108 milliseconds
imageLabel->setPixmap(QPixmap::fromImage(Image)); // takes 58 milliseconds
}

因为我不再需要将newImage设置为图像类成员,所以我只需使用newImage的引用并节省时间。但我很惊讶。

void ImageViewer::setImage(const QImage &newImage)
{
imageLabel->setPixmap(QPixmap::fromImage(newImage)); // takes 158 milliseconds
}

它需要相同的时间。我在这里错过了什么?

编辑 对于那些想知道我如何测量时间的人,我使用了这里建议的QElapsedTimer

图像每次都相同,代码是自定义滚动的一部分。您必须知道的是,每次我们输入此功能时,都会加载大小为2380x3368的相同图像(.jpg(。每次在评论中测量的时间几乎相同,都是平均时间。

但个人认为图像格式或大小不是这里的主要问题。主要问题应该是为什么当我使用引用到现有QImage时,SetPixmap需要更多时间,而不是创建一个新的QImage然后发送到这个函数。这没有任何意义。

来自文档: http://doc.qt.io/qt-5/qimage.html#operator-eq

QImage &QImage:

:operator=(const QImage &image( 将给定图像的表副本分配给此图像,并返回对此图像的引用。

因此,我们可以确定您的两个代码块实际上是等效的,因为制作图像的写入时复制副本基本上是一个自由操作(当查看毫秒时间尺度时(。

在您的第一个示例中,看起来花费了大量时间进行初始复制,这一事实可能是您如何对代码进行基准测试的产物。

写入时编辑意味着ImagenewImage在分配后共享基础数据,并在其中一个数据出现分歧时按需创建数据的副本。实际上,它并不比复制指针贵多少。

QPixmap是围绕特定格式的内部QImage的薄包装器。您需要将调用分解为两个单独的调用,并确定格式转换是否需要时间 - 这是图像到像素图转换需要大量时间的唯一方法。当源图像具有正确的格式时,转换根本不需要时间。

void ImageViewer::setImage(const QImage &newImage) {
static auto const format = QPixmap(1,1).toImage().format();
if (format != newImage.format())
qWarning("There is a format conversion. This won't be fast.");
QElapsedTimer timer;
timer.start();
auto const pixmap = QPixmap::fromImage(newImage);
auto time = timer.elapsed();
qDebug() << "Pixmap conversion took" << time << "ms.";
imageLabel->setPixmap(pixmap);
time = timer.elapsed();
qDebug() << "Pixmap setting took" << time << "ms.";
}