QPixmap QImage QBitmap QPicture區別

新版qt不支持xp系統,如果需要高版本的qt支持xp系統,需要重新編譯源碼看

QTreeWidget,QTreeView官方demo實例會卡死,QTreeWidget,QTreeView存在bug和性能上的問題,參考了其他產品的tree widget結構,有些不是用系統自帶的tree widget做出來的,需自己自繪製的,所以可以不用qt自帶的QTreeWidget,QTreeView做tree widget窗口,可以自己繪製出來。

QPixmap用於圖片的顯示設計和優化,QPixmap顯示更快,但是存儲空間不夠時,會顯示異常

QImage用於圖片的顯示和單個像素的訪問和編輯,比如樣色板等功能可以使用

QBitmap用於深度爲1的圖片比如光標遊標,圖像比較簡單的圖片

QPicture用於圖像的播放等功能,自定義動畫等功能可以使用

二)QImage與QPixmap完全解析

用Qt程序在手機上顯示一幅圖片對編程人員來說是再基礎不過的一件事情了。那麼先讓大家看兩段代碼:

//dangerous should not be used, cannot display earth.png,  
//but if we change earth.png to a smaller image e.g. apple.png, apple.png can be displayed
QPixmap pixmap;
pixmap.load( ":/pics/earth.png" );
label->setPixmap( pixmap );


//dangerous should not be used, cannot display earth.png,  
//but if we change earth.png to a smaller image e.g. apple.png, apple.png can be displayed
QPixmap pixmap;
pixmap.load( ":/pics/earth.png" );
QPainter painter(this);
painter.drawPixmap(0,0, pixmap);
大家認爲這兩段代碼有什麼問題嗎? 看起來好像沒什麼問題啊。是的,在Windows操作系統上是沒有問題的。問題是我們做的是Qt for Symbian! 手機上的資源本來就是比較緊缺的,所以我們使用的時候就需要更加註意。 Qt 爲我們提供了四個處理圖像的類:QImage,QPixmap,QBitmap 和QPicture。其中前兩個是最常使用的。

本文就通過一個例子,一步一步爲大家講解QImage與QPixmap的使用奧祕,在此過程中爲大家揭示以上代碼存在的缺陷。

QPixmap依賴於硬件

首先需要知道的是QPixmap的具體實現是依賴於系統的。在Symbian系統上QPixmap是被存放在Server端的。 
目前的Qt會把QPixmap都存儲在graphics memory中,這明顯是依賴硬件的。因此我們對QPixmap的使用需要格外注意。這也正是以上兩段代碼存在問題的根源。
那麼Qt爲什麼要這麼做呢?很簡單,設計之初QPixmap就是用來加速顯示的,例如我們在paint的時候用QPixmap就會比用其他類的效果好許多。

現在回到我們最初的問題,以上代碼到底有什麼問題呢?我們可以先用本文提供的例子程序做個試驗。當使用上述代碼顯示較小圖片的時候(比如例子程序中的background.png 和apple.png)是沒有問題的,圖片都能在手機上正確顯示。
但是當我們把圖片換成一副較大圖片287KB,1058 x 1058的“earth.png”的時候就出現問題了,圖片無法顯示,程序的界面是一片空白。

據測算,“earth.png”被完全解碼後存儲在graphics memory中會佔用大約4.3MB的空間。如果此時還有其他加載的窗口和QPixmap,很可能就沒有空間了。

使用QImage加載後轉換成QPixmap 顯示

那麼安全和正確的方法應該是什麼呢?答案是我們需要用QImage做一下預處理:

//correct and recommended way
QImage image;
image.load( ":/pics/earth.png" );

QPainter painter(this);
QPixmap pixmapToShow = QPixmap::fromImage( image.scaled(size(), Qt::KeepAspectRatio) );
painter.drawPixmap(0,0, pixmapToShow);
和QPixmap 不同,QImage是獨立於硬件的,它可以同時被另一個線程訪問。QImage是存儲在客戶端的,對QImage的使用是非常方便和安全的。 又由於 QImage 也是一種QPaintDevice,因此我們可以在另一個線程中對其進行繪製,而不需要在GUI 線程中處理,使用這一方式可以很大幅度提高UI響應速度。 因此當圖片較大時,我們可以先通過QImage將圖片加載進來,然後把圖片縮放成需要的尺寸,最後轉換成QPixmap 進行顯示。

其中需要注意的是Qt::KeepAspectRatio的使用,默認參數是Qt::IgnoreAspectRatio,如果我們在程序中這麼寫:QPixmap pixmapToShow = QPixmap::fromImage( image.scaled(size(), Qt::IgnoreAspectRatio) );
 

我們也可以直接使用QImage做顯示,而不轉換成QPixmap ,這要根據我們應用的具體需求來決定,如果需要的話我們可以這麼寫:

//correct, some times may be needed
QImage image;
image.load( ":/pics/earth.png" );

QPainter painter(this);
painter.drawImage(0,0, image);

 

QPixmap在手機上顯示時如果圖片過大,會顯示不出來的,因爲它是依賴於硬件的,存放到

graphics memory(顯存,顯示內存)的,所以需要將圖片放小才能放下,如果需要將大的圖片放到手機上顯示出來,需要將圖片轉小,有一下方式實現:

  1. 直接使用小的圖片顯示即可
  2. 如果一定要使用大的圖片,比如有的手機屏幕尺寸不同有的3寸,4寸,到10寸多大的平板電腦等,可以將大的圖片轉爲小的圖片即可,如一下方式:

QImage image;
image.load( ":/pics/earth.png" );

QPixmap pixmapToShow = QPixmap::fromImage( image.scaled(size(), Qt::KeepAspectRatio) );

其中的size()很重要,如果設置的值大小有誤,超過了屏幕大小導致顯存不夠會顯示不出來,所以size()大小需要適當,如果取得size()還是原先的image的size,大小沒有變,還是顯示不出來的,因爲過大了,size()大小需要小於屏幕大小更安全。

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章