Как я могу изменить размер изображения так быстро, как QLabel? - PullRequest
0 голосов
/ 20 марта 2011

Я пытаюсь написать приложение на основе Qt, которое отображает и манипулирует изображениями.
Я хочу, чтобы изображение всегда увеличивалось до размера окна, сохраняя его соотношение сторон.
К сожалению, в QLabel нетвозможность сохранить соотношение сторон прикрепленного растрового изображения.
Итак, я написал собственный виджет и реализовал resizeEvent () и paintEvent (), чтобы изменить размер изображения
и нарисовать его:

   class MyLabel : public QWidget
   {
     Q_Object

   public:
     MyLabel(): pixmap("test.tif") {} 

   protected:
     void resizeEvent(QResizeEvent *event)
     {
       pixmap_scaled = pixmap.scaled(size(), Qt::KeepAspectRatio);
     }

     void paintEvent(QPaintEvent *event)
     {
       QPainter p(this);
       p.drawPixmap(0, 0, pixmap_scaled);
       p.end();
     }

   private:
     QPixmap pixmap, pixmap_scaled;
   };  

Ноизменение размера изображения происходило не так гладко, как в QLabel.

Затем я смотрю на функцию paintEvent QLabel в qlabel.cpp, чтобы увидеть, как она отображает растровое изображение.
Там кажется, что растровое изображение - один разпреобразовал в QImage и масштабировал до размера окна,
, а затем снова преобразовал в QPixmap.
Я был немного удивлен, потому что преобразование между QPixmap и QImage - дорогостоящая операция
согласно справочному руководству Qt, ноЯ попытался переписать paintEvent () моего виджета, чтобы сделать то же самое
, что и QLabel :: paintEvent ().Затем изменение размера стало намного медленнее, чем ожидалось.

Интересно, почему изменение размера QLabel происходит так быстро?Является ли это преимуществом «неявного совместного использования данных»?
Конечно, невозможно просто скопировать paintEvent () из QLabel в мой класс, потому что недоступны частные данные
, такие как «указатель d».

Буду признателен за любую помощь.

Ответы [ 3 ]

1 голос
/ 22 марта 2011

Несколько общих замечаний, которые могут помочь.

  1. Если вы преобразуетесь в QImage один раз и сохраняете ссылку на QImage, это, вероятно, немного улучшит производительность.Тогда вам нужно будет только масштабировать и преобразовать обратно в событии рисования.
  2. В событии изменения размера отметьте, что изображение необходимо изменить, но не делайте этого, пока вы не начнете рисовать.Qt будет объединять события рисования, когда это возможно, и таким образом вы избегаете масштабирования, просто масштабируясь снова перед рисованием.
  3. Подумайте над поиском «шагов» и сохранением там кэшированных изображений, если вы часто увеличиваете и уменьшаете размер.По возможности покажите эти шаги и выберите шаг, который хорошо масштабируется (обычно кратно 2) для текущего размера, когда это невозможно.
  4. Попробуйте не масштабировать изображение напрямую, а вместо этого использовать преобразование рисования.Это может переложить работу по масштабированию с ЦП на преобразование ГП, что часто будет быстрее.В этой ситуации вы всегда хотите нарисовать изображение в натуральную величину и позволить преобразованию идти вверх или вниз.
0 голосов
/ 22 марта 2011

Спасибо за ответ.

Но, как я уже писал выше, реализация моего paintEvent () для масштабирования QImage и преобразования его обратно в QPixmap закончилась гораздо более низкой производительностью.
Поэтому я предполагаю, что в QLabel используется какая-то особая техника ...

0 голосов
/ 21 марта 2011

Из подробного описания QPixmap:

QImage разработан и оптимизирован для ввода-вывода, а также для прямого доступа и манипулирования пикселями, а QPixmap разработан и оптимизирован для отображения изображений на экране.

Поэтому я предполагаю, что быстрее масштабировать QImage и преобразовать его обратно в QPixmap, чем масштабировать QPixmap

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