2011-03-20 78 views
0

我正试图编写一个基于Qt的应用程序来显示和操作图像。
我想要图像始终展开为保持其纵横比的窗口大小。
不幸的是,QLabel没有选项来保持附加像素图的高宽比。
所以我写了一个自定义窗口小部件和实施resizeEvent()和的paintEvent()调整图像
,写生:如何像QLabel一样快速调整图像大小?

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做调整。

然后我看看qlabel.cpp中的QLabel的paintEvent函数,看看它是如何显示像素图的。
看来像素图曾经被转换为QImage并缩放到窗口大小
,然后再次转换为QPixmap。
我有点惊讶,因为QPixmap的QImage的和之间的转换是根据Qt的参考手册昂贵的操作
,但我想我的窗口小部件的改写的paintEvent()做同样的事情
作为QLabel ::的paintEvent()。然后,调整大小变得如预期慢得多。

我想知道为什么调整QLabel的速度如此之快。它是“隐式数据共享”的好处吗?
当然,因为私人数据
(如“d指针”)无法访问,所以将QLabel的paintEvent()复制到我的类是不可能的。

任何帮助,将不胜感激。

回答

0

从的QPixmap详细描述:

QImage的被设计和优化用于I/O,以及用于直接像素访问和操作,而的QPixmap被设计和用于在屏幕上显示的图像进行了优化。

所以我猜测它的速度更快QImage的扩展和转换回的QPixmap,比缩放的QPixmap

0

谢谢你的答复。

但正如我上面写的,实现我的paintEvent()来缩放QImage并将其转换回QPixmap最终导致性能更差。
所以我想在QLabel中使用某种特殊的技术...

1

几个一般的意见,可能会有所帮助。

  1. 如果您转换为QImage一次并保留对QImage的引用,那可能会提高某些性能。那么您只需要在绘画事件中进行缩放和转换。
  2. 在resize事件中,标记图像需要重新缩放,但不要在绘画之前进行。 Qt会尽可能地组合绘画事件,这样可以避免缩放,只是在绘画之前再次缩放。
  3. 考虑寻找“步骤”,并保持缓存的图像,如果你经常大小上下。尽可能显示这些步骤,并在不可能的情况下为当前大小选择一个可以很好地缩放的步骤(通常以2的倍数)。
  4. 请考虑不要直接缩放图像,而应使用画笔转换。这可能会将缩放工作从CPU转移到GPU转换,这通常会更快。在这种情况下,您总是希望全尺寸地绘制图像,并让变换向上或向下。