2011-03-20 101 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轉換,這通常會更快。在這種情況下,您總是希望全尺寸地繪製圖像,並讓變換向上或向下。