Странные времена выполнения при установке pixmap в Qt - PullRequest
0 голосов
/ 31 мая 2018

Посмотрите на следующий код: Image является членом класса типа QImage .

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

, потому что мне не нужно устанавливать newImage to Image член класса, я просто использую ссылку newImage и экономлю время.Но я был удивлен.

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

Это занимает то же время.Что мне здесь не хватает?

РЕДАКТИРОВАТЬ Для тех, кто хочет узнать, как я измерял время, я использовал предложенный QElapsedTimer здесь

Изображение всегда одно и то же, часть кодаВыкл. пользовательский свиток.Все, что вам нужно знать, это то же изображение (.jpg) размером 2380x3368, которое загружается каждый раз, когда мы входим в эту функцию.Измеренное время почти всегда одинаково, если в комментариях указано среднее время.

Но лично я считаю, что формат изображения или его размер здесь не главный вопрос.Главный вопрос должен заключаться в том, почему SetPixmap занимает больше времени, когда я использовал ref для существующего QImage, чем для создания нового QImage, который затем отправляется этой функции.Это не имеет никакого смысла.

Ответы [ 2 ]

0 голосов
/ 01 июня 2018

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.";
}
0 голосов
/ 31 мая 2018

Из документации: http://doc.qt.io/qt-5/qimage.html#operator-eq

QImage & QImage :: operator = (const QImage & image) Назначает неглубокую копию данного изображения этому изображению и возвращаетссылка на это изображение.

Таким образом, мы можем установить, что оба ваших блока кода фактически эквивалентны, поскольку создание копии изображения при копировании при записи является в основном бесплатной операцией (если смотреть наШкалы времени в миллисекундах).

Тот факт, что на создание первого экземпляра в первом примере уходит много времени, вероятно, является артефактом того, как вы тестировали код.

Редактировать Копирование при записи означает, что и Image, и newImage совместно используют базовые данные после назначения и будут делать копию данных по требованию при первом расхождении одного из них.По сути, это не намного дороже, чем копирование указателя.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...